Statistics
11
Views
0
Downloads
0
Donations
Support
Share
Uploader

高宏飞

Shared on 2026-05-23

AuthorMatt Neuburg

Covers iOS 14, Xcode 12, and Swift 5.3

Tags
No tags
ISBN: 1492092096
Publisher: O'Reilly Media
Publish Year: 2020
Language: 英文
Pages: 708
File Format: PDF
File Size: 7.8 MB
Support Statistics
¥.00 · 0times
Text Preview (First 20 pages)
Registered users can read the full content for free

Register as a Gaohf Library member to read the complete e-book online for free and enjoy a better reading experience.

Matt Neuburg iOS 14 Programming Fundamentals with Swift Swift, Xcode, and Cocoa Basics Covers iOS 14, Xcode 12, and Swift 5.3
(This page has no text content)
Matt Neuburg Boston iOS 14 Programming Fundamentals with Swift Swift, Xcode, and Cocoa Basics SEVENTH EDITION
ISBN: 978-1-492-09209-4 [GP] iOS 14 Programming Fundamentals with Swift, Seventh Edition by Matt Neuburg Copyright © 2021 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: Rachel Roumeliotis 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 Revision History for the Seventh Edition 2020-09-23: First Release See http://oreilly.com/catalog/errata.csp?isbn=9781492092094 for release details. The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. iOS 14 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. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii Part I. Language 1. The Architecture of Swift. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Ground of Being 3 Everything Is an Object? 5 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 34 Modifiable Parameters 35 Calling Objective-C with Modifiable Parameters 37 Called by Objective-C with Modifiable Parameters 38 Reference Type Modifiable Parameters 38 Function in Function 39 Recursion 40 Function as Value 40 Anonymous Functions 44 Using Anonymous Functions Inline 45 Anonymous Function Abbreviated Syntax 46 Define-and-Call 50 Closures 51 How Closures Improve Code 52 Function Returning Function 54 Closure Setting a Captured Variable 57 Closure Preserving Captured Environment 57 Escaping Closures 59 Curried Functions 60 Function References and Selectors 61 Function Reference Scope 63 Selectors 65 3. Variables and Simple Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 Variable Scope and Lifetime 67 Variable Declaration 69 Computed Variable Initialization 73 Computed Variables 74 Computed Properties 75 Property Wrappers 77 Setter Observers 78 Lazy Initialization 79 Singleton 80 Lazy Initialization of Instance Properties 80 Built-In Simple Types 82 Bool 82 Numbers 84 String 92 iv | Table of Contents
Character and String Index 97 Range 102 Tuple 104 Optional 106 4. Object Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 Object Type Declarations and Features 121 Initializers 123 Properties 130 Methods 133 Subscripts 134 Nested Object Types 137 Enums 138 Raw Values 139 Associated Values 141 Enum Case Iteration 143 Enum Initializers 144 Enum Properties 145 Enum Methods 146 Why Enums? 148 Structs 149 Struct Initializers 149 Struct Properties 151 Struct Methods 151 Struct as Namespace 152 Classes 152 Value Types and Reference Types 153 Subclass and Superclass 158 Class Initializers 164 Class Deinitializer 172 Class Properties 172 Static/Class Members 173 Polymorphism 174 Casting 178 Casting Down 179 Type Testing and Casting Down Safely 179 Type Testing and Casting Optionals 181 Bridging to Objective-C 182 Type References 183 From Instance to Type 183 Table of Contents | v
From self to Type 183 Type as Value 187 Summary of Type Terminology 188 Comparing Types 188 Protocols 189 Why Protocols? 191 Adopting a Library Protocol 192 Protocol Type Testing and Casting 193 Declaring a Protocol 194 Protocol Composition 194 Class Protocols 195 Optional Protocol Members 197 Implicitly Required Initializers 199 Expressible by Literal 200 Generics 201 Generic Declarations 204 Contradictory Resolution Is Impossible 206 Type Constraints 207 Explicit Specialization 209 Generic Invariance 211 Associated Type Chains 212 Where Clauses 214 Extensions 217 Extending Protocols 219 Extending Generics 221 Umbrella Types 223 Any 223 AnyObject 225 AnyClass 227 Collection Types 228 Array 228 Dictionary 244 Set 252 5. Flow Control and More. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 Flow Control 259 Branching 260 Loops 272 Jumping 278 Privacy 294 vi | Table of Contents
Private and Fileprivate 295 Public and Open 297 Privacy Rules 298 Introspection 298 Operators 299 Memory Management 303 Memory Management of Reference Types 303 Exclusive Access to Value Types 311 Miscellaneous Swift Language Features 313 Synthesized Protocol Implementations 313 Key Paths 316 Instance as Function 319 Dynamic Membership 320 Property Wrappers 322 Custom String Interpolation 325 Reverse Generics 327 Function Builders 329 Result 329 Part II. IDE 6. Anatomy of an Xcode Project. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335 New Project 335 The Project Window 337 The Navigator Pane 339 The Inspectors Pane 344 The Editor 345 Project File and Dependents 348 Contents of the Project Folder 349 Groups 350 The Target 351 Build Phases 351 Build Settings 353 Configurations 354 Schemes and Destinations 355 From Project to Built App 358 Build Settings 360 Property List Settings 361 Nib Files 362 Table of Contents | vii
Resources 362 Code Files 364 Frameworks, SDKs, and Packages 364 The App Launch Process 369 The Entry Point 369 How an App Gets Going 370 App Without a Storyboard 372 Renaming Parts of a Project 373 7. Nib Files. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375 The Nib Editor Interface 377 Document Outline 378 Canvas 380 Inspectors 382 Loading a Nib 383 Loading a View Controller Nib 383 Loading a Main View Nib 384 Loading a View Nib Manually 385 Connections 387 Outlets 387 The Nib Owner 389 Automatically Configured Nibs 392 Misconfigured Outlets 393 Deleting an Outlet 395 More Ways to Create Outlets 396 Outlet Collections 399 Action Connections 399 More Ways to Create Actions 401 Misconfigured Actions 403 Connections Between Nibs — Not! 404 Additional Configuration of Nib-Based Instances 404 8. Documentation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409 The Documentation Window 409 Class Documentation Pages 411 Quick Help 414 Symbol Declarations 416 Header Files 417 Sample Code 418 Internet Resources 419 viii | Table of Contents
9. Life Cycle of a Project. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421 Environmental Dependencies 421 Conditional Compilation 422 Build Action 423 Permissible Runtime Environment 424 Backward Compatibility 425 Device Type 426 Arguments and Environment Variables 428 Version Control 429 Editing and Navigating Your Code 432 Text Editing Preferences 433 Multiple Selection 434 Autocompletion and Placeholders 435 Snippets 436 Refactoring and Structure Editing 437 Fix-it and Live Syntax Checking 439 Navigation 439 Finding 441 Running in the Simulator 443 Debugging 445 Caveman Debugging 445 The Xcode Debugger 449 Testing 456 Unit Tests 458 Interface Tests 463 Test Plans 465 Massaging the Report 467 Clean 468 Running on a Device 469 Obtaining a Developer Program Membership 469 Signing an App 470 Automatic Signing 471 Manual Signing 474 Running the App 475 Managing Development Certificates and Devices 476 Profiling 477 Gauges 477 Memory Debugging 478 Instruments 479 Localization 482 Table of Contents | ix
Creating Localized Content 483 Testing Localization 487 Distribution 488 Making an Archive 488 The Distribution Certificate 489 The Distribution Profile 490 Distribution for Testing 491 Final App Preparations 493 Screenshots and Video Previews 495 Property List Settings 497 Submission to the App Store 498 Part III. Cocoa 10. Cocoa Classes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503 Subclassing 503 Categories and Extensions 506 How Swift Uses Extensions 506 How You Use Extensions 506 How Cocoa Uses Categories 507 Protocols 508 Optional Members 509 Informal Protocols 512 Some Foundation Classes 512 NSRange 513 NSNotFound 515 NSString and Friends 515 NSDate and Friends 518 NSNumber 520 NSValue 522 NSData 523 NSMeasurement and Friends 524 Equality, Hashability, and Comparison 524 NSArray and NSMutableArray 527 NSDictionary and NSMutableDictionary 529 NSSet and Friends 529 NSIndexSet 530 NSNull 531 Immutable and Mutable 532 x | Table of Contents
Property Lists 533 Codable 534 Accessors, Properties, and Key–Value Coding 537 Swift Accessors 539 Key–Value Coding 540 How Outlets Work 541 Cocoa Key Paths 541 Uses of Key–Value Coding 542 KeyPath Notation 543 The Secret Life of NSObject 545 11. Cocoa Events. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 547 Reasons for Events 547 Subclassing 548 Notifications 549 Receiving a Notification 551 Unregistering 553 Posting a Notification 554 Timer 555 Delegation 556 Cocoa Delegation 557 Implementing Delegation 558 Data Sources 560 Actions 561 The Responder Chain 564 Nil-Targeted Actions 565 Key–Value Observing 566 Registration and Notification 567 Unregistering 568 Key–Value Observing Example 569 Swamped by Events 571 Delayed Performance 574 12. Memory Management. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 577 Principles of Cocoa Memory Management 577 Rules of Cocoa Memory Management 578 What ARC Is and What It Does 579 How Cocoa Objects Manage Memory 580 Autorelease Pool 581 Memory Management of Instance Properties 583 Table of Contents | xi
Retain Cycles and Weak References 584 Unusual Memory Management Situations 586 Notification Observers 587 KVO Observers 588 Timers 588 Other Unusual Situations 590 Nib Loading and Memory Management 590 Memory Management of CFTypeRefs 591 Property Memory Management Policies 593 Debugging Memory Management Mistakes 595 13. Communication Between Objects. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 597 Visibility Through an Instance Property 597 Visibility by Instantiation 598 Getting a Reference 600 Visibility by Relationship 601 Global Visibility 601 Notifications and Key–Value Observing 603 The Combine Framework 604 Alternative Architectures 611 Model–View–Controller 611 Router and Data Space 611 Model–View–Presenter 612 Protocols and Reactive Programming 613 VIPER 614 SwiftUI 614 Function Builders and Modifiers 615 State Properties 616 Bindings 618 Passing Data Downhill 619 Passing Data Uphill 620 Custom State Objects 621 A. C, Objective-C, and Swift. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625 Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 663 xii | Table of Contents
Preface Ten years ago, 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 lan‐ guage, 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 all 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. xiii
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.3. 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 is intended to accompany and precede Programming iOS 14, which picks up where this book leaves off. If writing an iOS program is like building a house of bricks, this book teaches you what a brick is and how to handle it, while Program‐ ming iOS 14 shows you some actual bricks and tells you how to assemble them. When you have read this book, you’ll know about Swift, Xcode, and the underpin‐ nings of the Cocoa framework, and you will be ready to proceed directly to Program‐ ming iOS 14. Conversely, Programming iOS 14 assumes a knowledge of this book; it begins, like Homer’s Iliad, in the middle of the story, with the reader jumping with all four feet into views and view controllers, and with a knowledge of the language and the Xcode IDE already presupposed. If you started reading Programming iOS 14 and xiv | Preface
wondered about such unexplained matters as Swift language basics, the UIApplicationMain function, the nib-loading mechanism, Cocoa patterns of delega‐ tion and notification, and retain cycles, wonder no longer — I didn’t explain them there because I do explain them here. This book doesn’t show how to write any particularly interesting iOS apps, but it does constantly use my own real apps and real programming situations to illustrate and motivate its explanations, as it teaches you the underlying basis of iOS programming. It 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 (but such specialized topics as autolayout constraints in the nib are postponed to the other book). • 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 Preface | xv
solutions, I also discuss the new 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 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 prob‐ lem 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. xvi | Preface
A book, on the other hand, has numbered chapters and sequential pages; I can assume you know views before you know view controllers for the simple reason that Part I precedes Part II. And along with facts, I also bring to the table a degree of expe‐ rience, which I try to communicate to you. Throughout this book you’ll find me referring to “common beginner mistakes”; in most cases, these are mistakes that I have made myself, in addition to seeing others make them. I try to tell you what the pitfalls are because I assume that, in the course of things, you will otherwise fall into them just as naturally as I did as I was learning. You’ll also see me construct many examples piece by piece or extract and explain just one tiny portion of a larger app. It is not a massive finished program that teaches programming, but an exposition of the thought process that developed that program. It is this thought process, more than anything else, that I hope you will gain from reading this book. Versions This book is geared to Swift 5.3, iOS 14, and Xcode 12. In general, only very minimal attention is given to earlier versions of iOS and Xcode. Earlier versions can be very different from the current version, and it would be impossible to go into detail about all that has changed over the years. Besides, that information is readily and compendiously available in my earlier books. Recent inno‐ vations are called out clearly. The book does contain some advice about backward compatibility (especially in Chapter 9). I generally give method names in Swift, in the style of a function reference (as described in Chapter 2) — that is, the name plus parentheses containing the parame‐ ter labels followed by colon. Now and then, if a method is already under discussion and there is no ambiguity, I’ll use the bare name. In a few places, such as Appendix A, where the Objective-C language is explicitly under discussion, I use Objective-C method names. I have tried to keep my code up-to-date right up to the moment when the manuscript left my hands; but if, at some future time, a new version of Xcode is released along with a new version of Swift, some of the code in this book, and even some informa‐ tion about Swift itself, might be slightly incorrect. Please make allowances, and be prepared to compensate. Screenshots of Xcode were taken using Xcode 12 under macOS 11 Big Sur. I have waited until the last moment before publication to take these screenshots; I don’t expect the interface to have changed significantly by the time you read this, and if it does, the difference shouldn’t cause any confusion. Preface | xvii
Acknowledgments This book was written with the aid of some wonderful software: • Git (http://git-scm.com) • Sourcetree (http://www.sourcetreeapp.com) • TextMate (http://macromates.com) • AsciiDoc (http://www.methods.co.nz/asciidoc) • Asciidoctor (http://asciidoctor.org) • BBEdit (http://barebones.com/products/bbedit) • EasyFind (https://www.devontechnologies.com/support/download) • Snapz Pro X (http://www.ambrosiasw.com) • GraphicConverter (http://www.lemkesoft.com) • OmniGraffle (http://www.omnigroup.com) At O’Reilly Media, many people have made writing this book fun and easy; particular thanks go to Kristen Brown, Rachel Roumeliotis, Dan Fauxsmith, Adam Witwer, Nick Adams, Heather Scherer, Melanie Yarbrough, Sarah Schneider, and Sanders Kleinfeld. My first editor was Brian Jepson; his influence is present throughout. Finally, a special thanks to my beloved wife, Charlotte Wilson, for her sharp eye, her critical ear, and her unflagging encouragement. This book could not have been writ‐ ten without her. Conventions Used in This Book The following typographical conventions are used in this book: Italic Indicates new terms, URLs, email addresses, filenames, and file extensions. Constant width Used for program listings, as well as within paragraphs to refer to program ele‐ ments such as variable or function names, databases, data types, environment variables, statements, and keywords. Constant width bold Shows commands or other text that should be typed literally by the user. Constant width italic Shows text that should be replaced with user-supplied values or by values deter‐ mined by context. xviii | Preface