Statistics
7
Views
0
Downloads
0
Donations
Support
Share
Uploader

高宏飞

Shared on 2026-05-23

AuthorTutorial Team, raywenderlich, Todorov, Marin

Master Swift’s new concurrency model! For years, writing powerful and safe concurrent apps with Swift could easily turn into a daunting task, full of race conditions and unexplained crashes hidden in a massive nesting of callback closures. In Swift 5.5, Apple introduced a new concurrency model featuring the async/await syntax, to let you write asynchronous code that reads like synchronous code. But like any new feature, here be dragons! So how will you achieve the much-desired mastery of Modern Swift Concurrency? Master Swift’s new concurrency model! For years, writing powerful and safe concurrent apps with Swift could easily turn into a daunting task, full of race conditions and unexplained crashes hidden in a massive nesting of callback closures. In Swift 5.5, Apple introduced a new concurrency model featuring the async/await syntax, to let you write asynchronous code that reads like synchronous code. But like any new feature, here be dragons! So how will you achieve the much-desired mastery of Modern Swift Concurrency? The new concurrency model provides everything you need to write safe and performant programs in Swift, including: • A new, native syntax for running asynchronous operations in a structured way. • A bundle of standard APIs to design asynchronous and concurrent code. • Low-level changes in the libdispatch framework, which make all the high-level changes integrate directly into the operating system. • A new level of compiler support for creating safe, concurrent code. Swift 5.5 introduces the new language syntax and APIs to support these features. In your apps, besides using a recent Swift version, you also need to target certain platform versions: • If you’re using Xcode 13.2 or newer, it will bundle the new concurrency runtime with your app so you can target iOS 13 and macOS 10.15 (for native apps). • In case you’re on Xcode 13 but earlier version than 13.2, you’ll be able to target only iOS 15 or macOS 12 (or newer). In the first chapter of the boo

Tags
No tags
ISBN: 1950325539
Publisher: Razeware LLC
Publish Year: 2021
Language: 英文
Pages: 273
File Format: PDF
File Size: 29.2 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.

(This page has no text content)
Modern Concurrency in Swift By Marin Todorov Copyright ©2021 Razeware LLC. Notice of Rights All rights reserved. No part of this book or corresponding materials (such as text, images, or source code) may be reproduced or distributed by any means without prior written permission of the copyright owner. Notice of Liability This book and all corresponding materials (such as source code) are provided on an “as is” basis, without warranty of any kind, express of implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in action of contract, tort or otherwise, arising from, out of or in connection with the software or the use of other dealing in the software. Trademarks All trademarks and registered trademarks appearing in this book are the property of their own respective owners. Modern Concurrency in Swift Modern Concurrency in Swift raywenderlich.com 2
Table of Contents: Overview Book License 9................................................................................................ Before You Begin 10................................................................ What You Need 11........................................................................................ Book Source Code & Forums 12............................................................. Acknowledgments 16.................................................................................. Introduction 17.............................................................................................. Section I: Modern Concurrency in Swift 19..................... Chapter 1: Why Modern Swift Concurrency? 20................. Chapter 2: Getting Started With async/await 42................ Chapter 3: AsyncSequence & Intermediate Task 68........... Chapter 4: Custom Asynchronous Sequences With AsyncStream 92................................................................................. Chapter 5: Intermediate async/await & CheckedContinuation 117............................................................ Chapter 6: Testing Asynchronous Code 137......................... Chapter 7: Concurrent Code With TaskGroup 159............ Chapter 8: Getting Started With Actors 184........................ Chapter 9: Global Actors 211...................................................... Chapter 10: Actors in a Distributed System 230................. Conclusion 262.............................................................................................. Modern Concurrency in Swift raywenderlich.com 3
Table of Contents: Extended Book License 9. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Before You Begin 10. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . What You Need 11. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Book Source Code & Forums 12. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . About the Authors 14. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . About the Editors 14. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Acknowledgments 16. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction 17. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . How to read this book 18. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Section I: Modern Concurrency in Swift 19. . . . . . . . . . . Chapter 1: Why Modern Swift Concurrency? 20. . . . . . . . . . . . . . . Understanding asynchronous and concurrent code 21. . . . . . . . . . . . . . . . . . Introducing the modern Swift concurrency model 25. . . . . . . . . . . . . . . . . . . Running the book server 26. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Getting started with LittleJohn 28. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Writing your first async/await 29. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using async/await in SwiftUI 30. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using asynchronous sequences 33. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Canceling tasks in structured concurrency 37. . . . . . . . . . . . . . . . . . . . . . . . . . . Handling cancellation errors 39. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Challenges 40. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Key points 41. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 2: Getting Started With async/await 42. . . . . . . . . . . . . . . Pre-async/await asynchrony 42. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Separating code into partial tasks 45. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Controlling a task’s lifetime 46. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Modern Concurrency in Swift raywenderlich.com 4
Getting started 48. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A bird’s eye view of async/await 49. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Getting the list of files from the server 50. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Getting the server status 54. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Grouping asynchronous calls 56. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Asynchronously downloading a file 59. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Running async requests from a non-async context 61. . . . . . . . . . . . . . . . . . . A quick detour through Task 61. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Routing code to the main thread 64. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Updating the download screen’s progress 65. . . . . . . . . . . . . . . . . . . . . . . . . . . . Challenges 66. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Key points 67. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 3: AsyncSequence & Intermediate Task 68. . . . . . . . . . . . Getting to know AsyncSequence 69. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Getting started with AsyncSequence 70. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Canceling tasks 78. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Canceling an async task 78. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Manually canceling tasks 79. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Storing state in tasks 80. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Bridging Combine and AsyncSequence 84. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Challenges 89. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Key points 91. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 4: Custom Asynchronous Sequences With AsyncStream 92. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Getting started with the Blabber app 92. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Digging into AsyncSequence, AsyncIteratorProtocol and AsyncStream 98. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating an asynchronous timer with AsyncStream 102. . . . . . . . . . . . . . . . Adding an asynchronous stream to NotificationCenter 106. . . . . . . . . . . . Extending AsyncSequence 111. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Challenges 114. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Modern Concurrency in Swift raywenderlich.com 5
Key points 116. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 5: Intermediate async/await & CheckedContinuation 117. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introducing continuations 118. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating continuations manually 119. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Wrapping the delegate pattern 120. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Wrapping callback APIs with continuation 130. . . . . . . . . . . . . . . . . . . . . . . . . . Challenges 134. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Key points 136. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 6: Testing Asynchronous Code 137. . . . . . . . . . . . . . . . . . . . Capturing network calls under test 138. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating a model for testing 142. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Adding a simple asynchronous test 143. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Testing values over time with AsyncStream 144. . . . . . . . . . . . . . . . . . . . . . . . . Adding TimeoutTask for safer testing 148. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using async let to produce effects and observe them at the same time 153. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Speeding up asynchronous tests 156. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Key points 158. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 7: Concurrent Code With TaskGroup 159. . . . . . . . . . . . . Introducing TaskGroup 160. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Getting started with Sky 163. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Spawning tasks in a simple loop 165. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating a concurrent task group 167. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Controlling task execution 169. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Getting results from a task group 171. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mutating shared state 172. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Processing task results in real time 174. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Controlling the group flow 176. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Running code after all tasks have completed 178. . . . . . . . . . . . . . . . . . . . . . . . Modern Concurrency in Swift raywenderlich.com 6
Group error handling 179. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using the Result type with TaskGroup 181. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Key points 183. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 8: Getting Started With Actors 184. . . . . . . . . . . . . . . . . . . Understanding thread-safe code 185. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Meeting actor 188. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Recognizing the main actor 189. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Getting started with actors 190. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mutating state concurrently 192. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Showing the art and updating the progress 193. . . . . . . . . . . . . . . . . . . . . . . . . Detecting race conditions 195. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using actors to protect shared mutable state 197. . . . . . . . . . . . . . . . . . . . . . . Sharing data across actors 198. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Understanding Sendable 200. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Making safe methods nonisolated 202. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Designing more complex actors 202. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sharing the actor 206. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Key points 210. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 9: Global Actors 211. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Getting to meet GlobalActor 212. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Continuing with the EmojiArt project 214. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating a global actor 215. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating a safe silo 216. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Initializing the database actor 217. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Writing files to disk 218. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fetching images from disk (or elsewhere) 219. . . . . . . . . . . . . . . . . . . . . . . . . . . Purging the cache 221. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Wiring up the persistence layer 222. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Adding a cache hit counter 224. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Displaying the counter 226. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Purging the in-memory cache 227. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Modern Concurrency in Swift raywenderlich.com 7
Challenges: 228. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Key points 229. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 10: Actors in a Distributed System 230. . . . . . . . . . . . . . . . Going from local to distributed 232. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Getting started with SkyNet 234. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Enabling the network layer 235. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating an actor system 237. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Connecting to remote systems 238. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Adding a connectivity indicator 242. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sending a task to a remote system 246. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Managing a network request lifetime 247. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Receiving a response from a remote system 248. . . . . . . . . . . . . . . . . . . . . . . . Executing requests from other systems 250. . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sending a result back 251. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Handling incoming data 251. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Putting everything together 253. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Adding some UI bling 256. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Retrying failed tasks 257. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Key points 260. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Where to go from here? 261. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Conclusion 262. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Modern Concurrency in Swift raywenderlich.com 8
LBook License By purchasing Modern Concurrency in Swift, you have the following license: • You are allowed to use and/or modify the source code in Modern Concurrency in Swift in as many apps as you want, with no attribution required. • You are allowed to use and/or modify all art, images and designs that are included in Modern Concurrency in Swift in as many apps as you want, but must include this attribution line somewhere inside your app: “Artwork/images/designs: from Modern Concurrency in Swift, available at www.raywenderlich.com”. • The source code included in Modern Concurrency in Swift is for your personal use only. You are NOT allowed to distribute or sell the source code in Modern Concurrency in Swift without prior authorization. • This book is for your personal use only. You are NOT allowed to sell this book without prior authorization, or distribute it to friends, coworkers or students; they would need to purchase their own copies. All materials provided with this book are provided on an “as is” basis, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software. All trademarks and registered trademarks appearing in this guide are the properties of their respective owners. raywenderlich.com 9
Before You Begin This section tells you a few things you need to know before you get started, such as what you’ll need for hardware and software, where to find the project files for this book, and more. raywenderlich.com 10
iWhat You Need To follow along with this book, you’ll need the following: • A Mac running macOS Monterey (12.0) or later. Big Sur should work, but this book was written and tested on macOS Monterey, so your mileage may vary. • Xcode 13 or later. Xcode is the main development tool for iOS. You’ll need Xcode 13 or newer for the tasks in this book. If you’re using Xcode 13.2 and above, the new async/await syntax and the rest of the modern concurrency features will work starting with iOS 13 / macOS 10.15 SDK (or later). If you’re using an older version of Xcode 13, you’ll only get modern concurrency support when targeting iOS 15 / macOS 12. You can download the latest version of Xcode from Apple’s developer site (https://apple.co/2asi58y) • An intermediate level of Swift. Concurrency in general is a relatively advanced topic, so you need to have at least an intermediate-level knowledge of Swift and its existing concurrency features. This book won’t teach pre-Swift 5.5 Concurrency features such as Grand Central Dispatch, but you should still be able to follow the contents of this book, even if you’re not entirely proficient with them. This book does not require a physical device. However, you might want to try some of the advanced concurrency features on a real device, so you can truly feel how it works in “the real world”. raywenderlich.com 11
iiBook Source Code & Forums Where to download the materials for this book The materials for this book can be cloned or downloaded from the GitHub book materials repository: • https://github.com/raywenderlich/mcon-materials/tree/editions/1.0 Forums We’ve also set up an official forum for the book at https:// forums.raywenderlich.com/c/books/modern-concurrency-in-swift. This is a great place to ask questions about the book or to submit any errors you may find. raywenderlich.com 12
“Dedicated to my daughter and family. Warm thanks to everyone on the extended team that made this book possible.” — Marin Todorov raywenderlich.com 13
About the Authors Marin Todorov is a developer, speaker and author. He works for high-profile clients, most often doing Swift development.Besides crafting code, he enjoys blogging, writing books, teaching and speaking. He sometimes open-sources his code.More about Marin at: https://www.underplot.com About the Editors Rich Turton is a tech editor for this book. He’s been developing apps for Apple platforms since before it was cool. He lives in the UK with his wife, daughters and terrible cat. Felipe Laso Marsetti is a tech editor for this book. He’s a Technical Lead working at Lextech Global Services. In his spare time, Felipe enjoys learning new languages and frameworks, playing violin and guitar, cooking and also video games. You can follow him on Twitter as @iFeliLM (https://twitter.com/iFeliLM) or on his blog at https://programmer.pink. Sandra Grauschopf is the editor of this book. She’s a freelance writer, editor, and content strategist as well as the Editing Team Lead at raywenderlich.com. She loves to untangle tortured sentences and to travel the world with a trusty book in her hand. You can follow her on Twitter at https://twitter.com/sgrauschopf or learn more about her at https://grauschopf.com. Modern Concurrency in Swift About the Team raywenderlich.com 14
Shai Mishali is the final pass editor on this book. He’s an experienced, award-winning iOS specialist, an international speaker and a highly active open-source contributor and maintainer on several high-profile projects. He works on the RxSwift Community and RxSwift projects, but also releases many open-source endeavors around Combine such as CombineCocoa, RxCombine and more. As an avid enthusiast of hackathons, Shai took first place at BattleHack Tel-Aviv 2014, BattleHack World Finals San Jose 2014 and Ford’s Developer Challenge Tel-Aviv 2015. You can find him on GitHub (https://github.com/freak4pc) and Twitter as @freak4pc (https://twitter.com/freak4pc). Modern Concurrency in Swift About the Team raywenderlich.com 15
vAcknowledgments We would like to thank Audrey Tam, Marin Benčević and Piotr Fulmanski for their help in reviewing portions of this book and providing their feedback. raywenderlich.com 16
viIntroduction Welcome to Modern Concurrency in Swift, the book that walks you through the amazing new concurrency APIs introduced in Swift 5.5. Swift is a powerful, all-purpose programming language that’s currently expanding beyond Apple’s platforms (like iOS, macOS, tvOS and so on) and into new platforms like Linux, Windows, and more. To help the language take on a whole new set of tasks, Swift 5.5 introduced a modern concurrency model with a new native syntax for asynchronous operations and tighter integration between the concurrent APIs, the compiler and runtime. Most of the books from raywenderlich.com are “By Tutorials”. Since this book targets developers who already have intermediate/advanced Swift skills, however, we skipped that part of the book title. The book chapters consist of a healthy mix of theory sections that introduce new concepts and APIs, and step-by-step tutorials. If you work through all the projects, by the time you’re done, the new concurrency model won’t hold any secrets for you! Take a deep breath and enjoy the ride! raywenderlich.com 17
How to read this book Most of this book’s chapters build from one concept to the next. We suggest reading it chapter-by-chapter to make sure you aren’t missing any crucial knowledge you need for any of the advanced chapters. However, the chapters are also mostly self-contained, so if you feel comfortable with one of the topics, feel free to skip ahead to the next topic in the list. Modern Concurrency in Swift Introduction raywenderlich.com 18
Section I: Modern Concurrency in Swift raywenderlich.com 19
1Chapter 1: Why Modern Swift Concurrency? By Marin Todorov The last time Apple made a big deal about an asynchronous framework was when Grand Central Dispatch (GCD) came out, along with Mac OS X Snow Leopard, in 2009. While GCD helped Swift launch in 2014 with support for concurrency and asynchrony from day one, that support wasn’t native — it was designed around the needs and abilities of Objective-C. Swift just “borrowed” that concurrency until it had its own mechanism, designed specifically for the language. All that changed with Swift 5.5, which introduced a new, native model for writing asynchronous, concurrent code. The new concurrency model provides everything you need to write safe and performant programs in Swift, including: • A new, native syntax for running asynchronous operations in a structured way. • A bundle of standard APIs to design asynchronous and concurrent code. • Low-level changes in the libdispatch framework, which make all the high-level changes integrate directly into the operating system. • A new level of compiler support for creating safe, concurrent code. Swift 5.5 introduces the new language syntax and APIs to support these features. In your apps, besides using a recent Swift version, you also need to target certain platform versions: • If you’re using Xcode 13.2 or newer, it will bundle the new concurrency runtime with your app so you can target iOS 13 and macOS 10.15 (for native apps). raywenderlich.com 20