Preface xiii How This Book Is Organized xiiiAbout the Sample Code xivContacting the Author xv Chapter 1: Welcome to Modern Swift 1 Migrating Code 2How to Migrate 2Migration Lessons 4Using Swift 4Compiled Applications 4Frameworks and Libraries 5Scripting 5REPL 6Playgrounds 7Other Swift 8Learning Swift 8Wrap-up 9 Chapter 2: Printing and Mirroring 11 Basic Printing 11Printing Multiple Items 12Adding Item Separators 13String Interpolation 13Controlling Line Feeds 14Recipe: Printing to Custom Destinations 15Printing to Strings 16Printing to Custom Output Streams 17Recipe: Printing and String Formats 18Swift and Format Specifiers 19Format Limitations 19Conditional Compilation 20Debug Printing 21Custom Stream Output 21Recipe: Postfix Printing 23Quick Looks 24Quick Look for Custom Types 24Quick Looks for Custom Types in Playgrounds 25Playground Quick Looks 25Creating Custom Quick Looks for Playgrounds 26Built-in Quick Look Types 27Third-Party Rendering 28Using Dump Functions 30Building Custom Mirrors 31Recursive Reflection 32Building Basic Mirror Descriptions Using Protocol Conformance 33Adding Header Docs 35Building Header Documentation 35Markdown Support 36Keywords 37Special Swift Concerns 40Adding Images to Header Docs 40Wrap-up 41 Chapter 3: Optionals?! 43 Optionals 101 43Unwrapping Optionals 45Forced Unwrapping 45Conditional Binding 46Conditional Binding and Type Casts 46Binding Cascades 48guard Statements 50Implicitly Unwrapped Optionals 51Guarding Failable Initializers 52Optionals and Sentinel Values 53Coalescing 55Optional Assignment 55Optional Patterns 56Optional Chaining 58Selector Testing and Optional Chaining 59Subscripts 60Optional Mapping 61Maps and Chaining 61Filtering nil Values with flatMap 62Unmanaged Wrappers 62Wrap-up 64 Chapter 4: Closures and Functions 65 Building a Function 65Parameter Names 66Label Conventions 66Naming Methods and Functions 68External and Local Parameters 69Defaults 70Constant and Variable Parameters 71Modifying Parameters 72Closures and Functions 73Function Types 73Using Tuple Arguments 74Using Shorthand Argument Names 74Inferred Closure Types 76Parameter Type Inference 77Declaring Type Aliases 78Nested Functions 79Tuples 80From Tuples to Structs 82Tuple Return Types 82Variadic Parameters 83Capturing Values 85Autoclosures 87Adding Default Closures 90Currying 91Why Curry? 92Building Libraries 92Partial Application 93Currying Costs 94Currying and Callbacks 94Practical Currying 95Passing Closures as Function Parameters 97Wrap-up 99 Chapter 5: Generics and Protocols 101 Expanding to Generics 101Protocols 102Tokens 103Type Constraints 104Adopting Protocols 104Declaring Protocols 105Member Declarations 107Building a Basic Protocol 109Adding Protocol Default Implementations 110Optional Protocol Requirements 111Swift-Native Optional Protocol Requirements 112Building Generic Types 113Type Parameters 113Generic Requirements 114Conformance Requirements 115Recipe: Same-Type Requirements 115Generic Beautification 117Legal Tokens 117Matching Aliases 118Protocol Alias Defaults 119Collating Associated Types 119Extending Generic Types 120Using Protocols as Types 121Protocol-Based Collections 121Self Requirements 122Protocol Objects and Self Requirements 123Leveraging Protocols 124Wrap-up 124 Chapter 6: Errors 125 Failing Hard 125Fatal Errors 126Assertions 126Preconditions 127Aborting and Exiting 128Failing Gracefully 128The ErrorType Protocol 129Choosing Between Optionals and Error Handling 130Swift Error Rules 130Rule 1: Move Away from nil Sentinels 131Rule 2: Use throw to Raise Errors 132Rule 3: Use Error Types with Visible Access 133Rule 4: Mark All Error-Participating Methods with throws 134Rule 5: Use rethrows Consistently 134Rule 6: Consume Errors Where They Matter 135Rule 7: Terminate Threaded Error Chains 135Building Errors 137Good Errors 138Naming Your Errors 138Adding String Descriptions 139Adding Reasons 139Simplifying Output 140Extending String 140Type-Specific Errors 141Retrieving Context 141Contextualizing Strings 142Contextualizing Throwing Types 143Simplifying Contexts 144Calling Throwing Functions 145Using try 145Error Propagation 147Using try! 148Using try? 148Implementing Alternatives to try? 149Guarding Results 151Building a Printing Version of try? 151Working with guard and defer 151Wrap-up 153 Chapter 7: Types 155 Language Concepts 155Reference and Value Types 155Copy-and-Write-Back 156Algebraic Data Types 157Other Terminology 158Enumerations 159Basic Enumerations 159Using Hash Values to Support Ranges 160Raw Value Enumerations 162Raw Value Members and Sequences 163Associated Values 164Indirect Values 165Switches 166Branching 166Breaks 167Fallthroughs 167Complex Cases 169Tuples 169Pattern Matching with Value Bindings 169where Clauses 170Unwrapping Optional Enumerations 171Embedding Values by Type 172Option Sets 174Revisiting NS_OPTIONS 174Building Enumerations 175Building Option Sets 176Viewing Options 176Classes 177Optimization 178Initializers 178Initialization Steps 179Designated and Convenience Initializers 179Initialization Rules 179Building Convenience Initializers 181Failable and Throwing Initializers 181Deinitializers 183Property Observers 184Getters/Setters and Access-Level Modifiers 185Extensions and Overrides 186Lazy Evaluation 187Lazy Sequences 187Lazy Properties 188Wrap-up 188 Chapter 8: Miscellany 189 Statement Labels 189Custom Operators 190Declaring Operators 191Conforming with Operators 192Evaluating Operator Trade-offs 192Array Indexing 193Multi-indexed Array Access 194Wrapped Indices 195Array Slices 195General Subscripting 196Parameter-less Subscripting 197String Utilities 198Repeat Initializers 198Strings and Radix 198String Ranges 199String Splitting 201String Subscripts 201Foundation Interoperability 203Joining and Extending 203Permutation Generator 203Wrap-up 205 Index 207.
The Swift Developer's Cookbook