Matt Neuburg iOS 15 Programming Fundamentals with Swift Swift, Xcode, and Cocoa Basics Covers iOS 15, Xcode 13, and Swift 5.5
(This page has no text content)
Matt Neuburg Boston iOS 15 Programming Fundamentals with Swift Swift, Xcode, and Cocoa Basics EIGHTH EDITION
ISBN: 978-1-098-11850-1 [LSI] iOS 15 Programming Fundamentals with Swift, Eighth Edition by Matt Neuburg Copyright © 2022 Matt Neuburg. All rights reserved. Printed in the United States of America. Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472. O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (http://oreilly.com). For more information, contact our corporate/institu‐ tional sales department: 800-998-9938 or corporate@oreilly.com. Editor: Suzanne McQuade Indexer: Matt Neuburg Production Editor: Kristen Brown Cover Designer: Karen Montgomery Proofreader: O’Reilly Production Services Interior Designer: David Futato Illustrator: Matt Neuburg April 2015: First Edition October 2015: Second Edition October 2016: Third Edition October 2017: Fourth Edition September 2018: Fifth Edition October 2019: Sixth Edition October 2020: Seventh Edition October 2021: Eighth Edition Revision History for the Eighth Edition 2021-10-01: First Release See http://oreilly.com/catalog/errata.csp?isbn=9781098118501 for release details. The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. iOS 15 Programming Fundamentals with Swift, the image of a harp seal, and related trade dress are trademarks of O’Reilly Media, Inc. The views expressed in this work are those of the author, and do not represent the publisher’s views. While the publisher and the author have used good faith efforts to ensure that the information and instructions contained in this work are accurate, the publisher and the author disclaim all responsibility for errors or omissions, including without limitation responsibility for damages resulting from the use of or reliance on this work. Use of the information and instructions contained in this work is at your own risk. If any code samples or other technology this work contains or describes is subject to open source licenses or the intellectual property rights of others, it is your responsibility to ensure that your use thereof complies with such licenses and/or rights.
Table of Contents Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv Part I. Language 1. The Architecture of Swift. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Ground of Being 3 Everything Is an Object? 4 Three Flavors of Object Type 6 Variables 6 Functions 8 The Structure of a Swift File 9 Scope and Lifetime 12 Object Members 13 Namespaces 13 Modules 14 Instances 15 Why Instances? 17 The Keyword self 19 Privacy 20 Design 22 2. Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Function Parameters and Return Value 25 Void Return Type and Parameters 29 Function Signature 30 External Parameter Names 30 Overloading 32 iii
Default Parameter Values 33 Variadic Parameters 34 Ignored Parameters 35 Modifiable Parameters 36 Calling Objective-C with Modifiable Parameters 37 Called by Objective-C with Modifiable Parameters 38 Reference Type Modifiable Parameters 39 Function in Function 40 Recursion 40 Function as Value 41 Anonymous Functions 44 Using Anonymous Functions Inline 45 Anonymous Function Abbreviated Syntax 46 Define-and-Call 50 Closures 51 How Closures Improve Code 53 Function Returning Function 54 Closure Setting a Captured Variable 57 Closure Preserving Captured Environment 58 Escaping Closures 59 Capture Lists 60 Curried Functions 62 Function References and Selectors 63 Function Reference Scope 65 Selectors 67 3. Variables and Simple Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 Variable Scope and Lifetime 71 Variable Declaration 73 Computed Variable Initialization 77 Computed Variables 78 Computed Properties 79 Property Wrappers 81 Setter Observers 82 Lazy Initialization 83 Singleton 84 Lazy Initialization of Instance Properties 85 Built-In Simple Types 85 Bool 85 Numbers 88 iv | Table of Contents
String 96 Character and String Index 102 Range 106 Tuple 108 Optional 111 4. Object Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 Object Type Declarations and Features 125 Initializers 127 Properties 133 Methods 136 Subscripts 139 Nested Object Types 141 Enums 142 Raw Values 143 Associated Values 145 Enum Case Iteration 147 Enum Initializers 148 Enum Properties 149 Enum Methods 150 Why Enums? 152 Structs 153 Struct Initializers 153 Struct Properties 154 Struct Methods 155 Classes 156 Value Types and Reference Types 157 Subclass and Superclass 162 Class Initializers 168 Class Deinitializer 176 Class Properties 176 Static/Class Members 177 Polymorphism 178 Casting 182 Casting Down 183 Type Testing and Casting Down Safely 183 Type Testing and Casting Optionals 185 Bridging to Objective-C 186 Type References 187 From Instance to Type 187 Table of Contents | v
From self to Type 187 Type as Value 191 Summary of Type Terminology 192 Comparing Types 192 Protocols 193 Why Protocols? 194 Adopting a Library Protocol 195 Protocol Type Testing and Casting 197 Declaring a Protocol 197 Protocol Composition 198 Class Protocols 199 Optional Protocol Members 200 Implicitly Required Initializers 202 Expressible by Literal 204 Generics 205 Generic Declarations 208 Type Constraints 210 Explicit Specialization 212 Generic Types and Covariance 213 Associated Type Chains 215 Where Clauses 217 Extensions 220 Extending Protocols 222 Extending Generics 225 Umbrella Types 227 Any 227 AnyObject 229 AnyClass 231 Collection Types 232 Array 232 Dictionary 251 Set 258 OrderedSet and OrderedDictionary 263 5. Flow Control and More. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 Flow Control 269 Branching 270 Loops 282 Jumping 288 Privacy 305 vi | Table of Contents
Private and Fileprivate 306 Public and Open 308 Privacy Rules 309 Introspection 309 Operators 310 Memory Management 313 Memory Management of Reference Types 314 Exclusive Access to Value Types 321 Miscellaneous Swift Language Features 323 Synthesized Protocol Implementations 323 Key Paths 326 Instance as Function 329 Dynamic Membership 330 Property Wrappers 332 Custom String Interpolation 337 Reverse Generics 339 Result Builders 341 Result 341 6. Structured Concurrency. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343 Multithreading 344 The Main Thread 344 Background Threads 345 Asynchronous Code 347 Structured Concurrency Syntax 353 async/await 354 Async Contexts 355 Tasks 356 Wrapping a Completion Handler 357 Multiple Concurrent Tasks 361 async let 362 Task Groups 363 Asynchronous Sequences 367 Built-in Asynchronous Sequences 368 Making an Asynchronous Sequence 369 Asynchronous Sequence Methods 370 Actors 370 Actor Isolation 371 Actor Serialization 372 The Main Actor 372 Table of Contents | vii
Context Switching 374 Implicit Context Switching 374 Explicit Context Switching 375 More About Tasks 377 Task Priority 377 The Current Task 378 Sleeping 378 Yielding 379 Cancellation 380 More About Actors 386 Reentrancy 386 The Keyword nonisolated 387 The Keyword isolated 388 Global Actors 389 Sendable 390 Part II. IDE 7. Anatomy of an Xcode Project. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395 New Project 395 The Project Window 397 The Navigator Pane 399 The Inspector Pane 404 The Editor 405 Project File and Dependents 408 Contents of the Project Folder 409 Groups 410 The Target 411 Build Phases 411 Build Settings 413 Configurations 414 Schemes and Destinations 416 From Project to Built App 418 Build Settings 420 Property List Settings 420 Nib Files 421 Resources 421 Code Files 423 Frameworks and SDKs 424 viii | Table of Contents
Swift Packages 425 The App Launch Process 429 The Entry Point 429 How an App Gets Going 431 App Without a Storyboard 433 Renaming Parts of a Project 434 8. Nib Files. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437 The Nib Editor Interface 438 Document Outline 439 Canvas 442 Inspectors 443 Loading a Nib 444 Loading a View Controller Nib 445 Loading a Main View Nib 446 Loading a View Nib Manually 447 Connections 448 Outlets 449 The Nib Owner 450 Automatically Configured Nibs 454 Misconfigured Outlets 455 Deleting an Outlet 457 More Ways to Create Outlets 457 Outlet Collections 460 Action Connections 461 More Ways to Create Actions 463 Misconfigured Actions 464 Connections Between Nibs — Not! 465 Additional Configuration of Nib-Based Instances 466 9. Documentation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471 The Documentation Window 471 Class Documentation Pages 473 Quick Help 476 Documenting Frameworks and Packages 479 Symbol Declarations 482 Header Files 483 Sample Code 484 Internet Resources 484 Table of Contents | ix
10. Life Cycle of a Project. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487 Environmental Dependencies 487 Conditional Compilation 488 Build Action 489 Permissible Runtime Environment 490 Backward Compatibility 491 Device Type 492 Arguments and Environment Variables 494 Version Control 495 Editing and Navigating Your Code 498 Text Editing Preferences 499 Multiple Selection 500 Code Completion and Placeholders 501 Snippets 502 Refactoring and Code Actions 503 Fix-it and Live Syntax Checking 505 Navigation 506 Finding 509 Running in the Simulator 510 Debugging 512 Caveman Debugging 512 The Xcode Debugger 516 Testing 524 Unit Tests 527 Interface Tests 531 Test Plans 533 Massaging the Report 535 Clean 536 Running on a Device 537 Obtaining a Developer Program Membership 537 Signing an App 538 Automatic Signing 539 Manual Signing 541 Running the App 542 Managing Development Certificates and Devices 543 Profiling 543 Gauges 544 Memory Debugging 544 Instruments 546 Localization 548 x | Table of Contents
Creating Localized Content 548 Testing Localization 553 Distribution 554 Making an Archive 555 The Distribution Certificate 556 The Distribution Profile 557 Distribution for Testing 558 Final App Preparations 560 Screenshots and Video Previews 562 Property List Settings 563 Submission to the App Store 565 Part III. Cocoa 11. Cocoa Classes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 571 Subclassing 571 Categories and Extensions 574 How Swift Uses Extensions 574 How You Use Extensions 574 How Cocoa Uses Categories 575 Protocols 576 Optional Members 577 Informal Protocols 580 Some Foundation Classes 580 NSRange 581 NSNotFound 583 NSString and Friends 584 NSDate and Friends 587 NSNumber 590 NSValue 592 NSData 593 NSMeasurement and Friends 594 Equality, Hashability, and Comparison 595 NSArray and NSMutableArray 598 NSDictionary and NSMutableDictionary 600 NSSet and Friends 601 NSIndexSet 602 NSNull 603 Immutable and Mutable 603 Table of Contents | xi
Property Lists 604 Codable 605 Accessors, Properties, and Key–Value Coding 609 Swift Accessors 610 Key–Value Coding 611 How Outlets Work 612 Cocoa Key Paths 613 Uses of Key–Value Coding 614 KeyPath Notation 615 The Secret Life of NSObject 616 12. Cocoa Events. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 619 Reasons for Events 619 Subclassing 620 Notifications 621 Receiving a Notification 623 Unregistering 625 Subscribing to a Notification 626 Posting a Notification 628 Timer 629 Delegation 631 Cocoa Delegation 632 Implementing Delegation 633 Data Sources 635 Actions 636 The Responder Chain 639 Nil-Targeted Actions 640 Key–Value Observing 642 Registration and Notification 643 Unregistering 644 Key–Value Observing Example 645 Swamped by Events 647 Delayed Performance 649 13. Memory Management. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 653 Principles of Cocoa Memory Management 653 Rules of Cocoa Memory Management 654 What ARC Is and What It Does 655 How Cocoa Objects Manage Memory 656 Autorelease Pool 657 xii | Table of Contents
Memory Management of Instance Properties 659 Retain Cycles and Weak References 660 Unusual Memory Management Situations 662 Notification Observers 663 KVO Observers 664 Timers 665 Other Unusual Situations 666 Memory Management of CFTypeRefs 666 Property Memory Management Policies 668 Debugging Memory Management Mistakes 671 14. Communication Between Objects. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 673 Visibility Through an Instance Property 673 Visibility by Instantiation 674 Getting a Reference 676 Visibility by Relationship 677 Global Visibility 677 Notifications and Key–Value Observing 679 The Combine Framework 680 Alternative Architectures 687 Model–View–Controller 687 Router and Data Space 687 Model–View–Presenter 688 Protocols and Reactive Programming 689 SwiftUI 690 Result Builders and Modifiers 691 State Properties 692 Bindings 694 Passing Data Downhill 694 Passing Data Uphill 696 Custom State Objects 697 Appendix. C, Objective-C, and Swift. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 701 Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 739 Table of Contents | xiii
(This page has no text content)
Preface In July of 2010, Chris Lattner created a folder on his computer called Shiny, and a new computer language was born. Four years later, in 2014, that language, renamed Swift, was introduced to the public, and was greeted with a mixture of surprise and excitement — and skepticism. Prior to that moment, Cocoa programming, on iOS and before that on Mac OS, had always been done chiefly in Objective-C. The Cocoa frameworks that give an iOS app its functionality are based on Objective-C; they expect to be spoken to in Objective-C. The tradition of using Objective-C was long and deeply ingrained. For all its faults, Objective-C was the language we had learned to live with as the price of program‐ ming Cocoa. Could Cocoa be spoken to in a whole new language? Could this new language replace Objective-C as the iOS developer’s language of choice? No one knew. I certainly didn’t know! So the first thing I did, as an experiment, was to try translating my own existing iOS apps into Swift. Not only was I able to do it, but I found the new Swift versions easier to understand and maintain than their Objective-C originals. From that moment, I was convinced that the vast majority of new iOS programmers would hitherto adopt Swift. I was right. Swift is a superb language to learn, even (perhaps especially) if you’ve never program‐ med before, and is the easiest and clearest way to program iOS. It has these salient features: Object-orientation Swift is a modern, object-oriented language. It is purely object-oriented: “Every‐ thing is an object.” Clarity Swift is easy to read and easy to write. Its syntax is clear, consistent, and explicit, with few hidden shortcuts and minimal syntactic trickery. xv
Safety Swift enforces strong typing to ensure that it knows, and that you know, what the type of every object reference is at every moment. Economy Swift is a fairly small language, providing some basic types and functionalities and no more. The rest must be provided by your code, or by libraries of code that you use — such as Cocoa. Memory management Swift manages memory automatically. You will rarely have to concern yourself with memory management. Cocoa compatibility The Cocoa APIs are written primarily in C and Objective-C. Swift is explicitly designed to interface with most of the Cocoa APIs. Earlier editions of this book, before 2014, taught the reader Objective-C. After 2014, they teach Swift. This edition is geared to Swift 5.5. The Swift language has reached a high state of maturity. It has achieved ABI stability, which means that the Swift lan‐ guage has become part of the system. Swift apps are smaller and faster than ever. The Foundation and Cocoa APIs, however, are still written in C and Objective-C. To interact with them, you might have to know what those languages would expect. Therefore in this book I describe Objective-C in enough detail to allow you to read it when you encounter it in the documentation and on the internet, and I occasionally show some Objective-C code. Part III, on Cocoa, is largely about learning to think the way Objective-C thinks — because the structure and behavior of the Cocoa APIs are fundamentally based on Objective-C. And the book ends with an appendix that details how Swift and Objective-C communicate with one another, as well as explain‐ ing how your app can be written partly in Swift and partly in Objective-C. The Scope of This Book This book doesn’t teach you how to write any practical iOS programs. It’s about the fundamental underpinnings of iOS programming, the basics that you need to under‐ stand from the outset in order to get started. If writing an iOS program is like build‐ ing a house of bricks, this book teaches you what a brick is and how to handle it; actually assembling the bricks comes later. In this book, you’ll learn all about: • The programming language you’ll be writing in (Swift). • The milieu in which you’ll be writing, editing, running, testing, and generally developing (Xcode). • The framework you’ll be communicating with as your app runs (Cocoa). xvi | Preface
When you have read this book, you’ll know about Swift, Xcode, and the nature of the Cocoa framework, and you will be ready to proceed to learn about real-life iOS app components such as views and view controllers. And even though the book doesn’t show how to write any particularly interesting iOS apps, it does constantly use my own real apps and real programming situations to illustrate and motivate its explana‐ tions, as it teaches you the underlying basis of iOS programming. The book has three parts: • Part I introduces the Swift language, from the ground up — I do not assume that you know any other programming languages. My way of teaching Swift is differ‐ ent from other treatments, such as Apple’s; it is systematic and Euclidean, with pedagogical building blocks piled on one another in what I regard as the most helpful order. At the same time, I have tried to confine myself to the essentials. Swift is not a big language, but it has some subtle and unusual corners that you probably don’t need to know about. Also, I never mention Swift playgrounds or the REPL. My focus here is real-life iOS programming, and my explanation of Swift concentrates on the practical aspects of the language that actually come into play in the course of programming iOS. • Part II turns to Xcode, the world in which all iOS programming ultimately takes place. It explains what an Xcode project is and how it is transformed into an app, and how to work comfortably and nimbly with Xcode to consult the documenta‐ tion and to write, navigate, and debug code, as well as how to bring your app through the subsequent stages of running on a device and submission to the App Store. There is also a chapter on nibs and the nib editor (Interface Builder), including outlets and actions as well as the mechanics of nib loading. • Part III introduces the Cocoa Touch framework. The Foundation and UIKit frameworks, and other frameworks that they entail, constitute Cocoa, which pro‐ vides the underlying functionality that any iOS app needs to have. To use a framework effectively, you have to think the way the framework thinks, put your code where the framework expects it, and fulfill many obligations imposed on you by the framework. Also, Cocoa uses Objective-C, so you need to know how your Swift code will interface with Cocoa’s features and behaviors. Cocoa pro‐ vides important foundational classes and adds linguistic and architectural devices such as categories, protocols, delegation, and notifications, as well as the perva‐ sive responsibilities of memory management. Key–value coding and key–value observing are also discussed here. The last chapter of Part III is about the general problem of how objects can refer to one another in an iOS program. In addition to the traditional Cocoa-based solutions, I also discuss the Swift Combine framework. Also, in June of 2019, Apple introduced SwiftUI. It constitutes an alternative to UIKit and Cocoa, with a completely different programming paradigm for constructing apps. I do not Preface | xvii
teach SwiftUI in this book — that would require another entire book — but I do explain its chief linguistic features, and I talk about its solutions to the problem of communicating between objects within an iOS app and how they differ from Cocoa patterns. From the Preface to the First Edition (Programming iOS 4) The popularity of the iPhone, with its largely free or very inexpensive apps, and the subsequent popularity of the iPad, have brought and will continue to bring into the fold many new programmers who see programming for these devices as worthwhile and doable, even though they may not have felt the same way about OS X. Apple’s own annual WWDC developer conventions have reflected this trend, with their emphasis shifted from OS X to iOS instruction. The widespread eagerness to program iOS, however, though delightful on the one hand, has also fostered a certain tendency to try to run without first learning to walk. iOS gives the programmer mighty powers that can seem as limitless as imagination itself, but it also has fundamentals. I often see questions online from programmers who are evidently deep into the creation of some interesting app, but who are sty‐ mied in a way that reveals quite clearly that they are unfamiliar with the basics of the very world in which they are so happily cavorting. It is this state of affairs that has motivated me to write this book, which is intended to ground the reader in the fundamentals of iOS. Here I have attempted to marshal and expound, in what I hope is a pedagogically helpful and instructive yet ruthlessly Euclidean and logical order, the principles and elements on which sound iOS pro‐ gramming rests. My hope, as with my previous books, is that you will both read this book cover to cover (learning something new often enough to keep you turning the pages) and keep it by you as a handy reference. This book is not intended to disparage Apple’s own documentation and example projects. They are wonderful resources and have become more wonderful as time goes on. I have depended heavily on them in the preparation of this book. But I also find that they don’t fulfill the same function as a reasoned, ordered presentation of the facts. The online documentation must make assumptions as to how much you already know; it can’t guarantee that you’ll approach it in a given order. And online documentation is more suitable to reference than to instruction. A fully written example, no matter how well commented, is difficult to follow; it demonstrates, but it does not teach. xviii | Preface
Comments 0
Loading comments...
Reply to Comment
Edit Comment