Table Of ContentSwiftUI Apprentice
SwiftUI Apprentice
By Audrey Tam & Caroline Begbie
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.
raywenderlich.com 2
SwiftUI Apprentice
Table of Contents: Overview
Book License............................................................................................. 14
Before You Begin................................................................ 15
What You Need........................................................................................ 16
Book Source Code & Forums............................................................. 17
About the Cover...................................................................................... 18
How to Read This Book........................................................................ 23
Section I: Your first app: HIITFit.................................... 24
Chapter 1: Checking Your Tools............................................ 25
Chapter 2: Planning a Paged App......................................... 60
Chapter 3: Prototyping the Main View.............................. 79
Chapter 4: Prototyping Supplementary Views............ 107
Chapter 5: Organizing Your App's Data.......................... 130
Chapter 6: Adding Functionality to Your App.............. 156
Chapter 7: Observing Objects............................................ 176
Chapter 8: Saving Settings................................................... 192
Chapter 9: Saving History Data.......................................... 218
Chapter 10: Refining Your App........................................... 246
Chapter 11: Understanding Property Wrappers........ 277
Chapter 12: Apple App Development Ecosystem...... 298
Section II: Your second app: Cards............................. 321
Chapter 13: Outlining a Photo Collage App.................. 322
raywenderlich.com 3
SwiftUI Apprentice
Chapter 14: Gestures............................................................. 346
Chapter 15: Structures, Classes & Protocols................ 374
Chapter 16: Adding Assets to Your App......................... 405
Chapter 17: Interfacing With UIKit.................................. 435
Chapter 18: Paths & Custom Shapes............................... 454
Chapter 19: Saving Files........................................................ 479
Chapter 20: Delightful UX — Layout................................ 506
Chapter 21: Delightful UX — Final Touches.................. 535
Section III: Your third app: RWFreeView................. 565
Chapter 22: Lists & Navigation........................................... 566
Chapter 23: Just Enough Web Stuff................................. 596
Chapter 24: Downloading Data......................................... 625
Chapter 25: Implementing Filter Options..................... 652
Chapter 26: Widgets.............................................................. 680
Conclusion.............................................................................................. 706
raywenderlich.com 4
SwiftUI Apprentice
Table of Contents: Extended
Book License. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Before You Begin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
What You Need . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Book Source Code & Forums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
About the Cover . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
About the Authors. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
About the Editors. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
About the Artist. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
How to Read This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Section I: Your first app: HIITFit. . . . . . . . . . . . . . . . . . . . 24
Chapter 1: Checking Your Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Getting started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Creating a new Xcode project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
A quick tour of Xcode. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
ContentView.swift. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Creating a new SwiftUI View file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
What else is in your project?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Xcode Preferences. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Running your project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Key points. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Chapter 2: Planning a Paged App . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Making lists: views and actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Creating Pages. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Grouping files. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Passing parameters. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Looping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
raywenderlich.com 5
SwiftUI Apprentice
Key points. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
Where to go from here?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
Chapter 3: Prototyping the Main View . . . . . . . . . . . . . . . . . . . . . . 79
Creating the Exercise view . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Creating the Header view . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
Playing a video. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Finishing the Exercise view . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
Key points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Where to go from here?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Chapter 4: Prototyping Supplementary Views. . . . . . . . . . . . . 107
Creating the History view. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Creating the Welcome view. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Challenge. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
Key points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
Where to go from here?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
Chapter 5: Organizing Your App's Data . . . . . . . . . . . . . . . . . . . . 130
Creating the Exercise structure. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
Structuring HistoryView data. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
Localizing your app. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
Key points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
Chapter 6: Adding Functionality to Your App . . . . . . . . . . . . . . 156
Managing your app’s data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
Navigating TabView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
Interacting with page numbers and ratings . . . . . . . . . . . . . . . . . . . . . . . . . 164
Showing and hiding modal sheets. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
Key points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
Chapter 7: Observing Objects. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
Showing/Hiding the timer. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
Adding an exercise to history. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
Challenge. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
raywenderlich.com 6
SwiftUI Apprentice
Key points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
Chapter 8: Saving Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
Data persistence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Saving the ratings to UserDefaults. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Data directories. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
Swift Dive: Strings. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
Thinking of possible errors. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
Multiple scenes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
Apps, Scenes and Views. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
Restoring scene state with SceneStorage. . . . . . . . . . . . . . . . . . . . . . . . . . . 215
Key points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
Chapter 9: Saving History Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
Using optionals. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
Debugging HistoryStore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
Swift error checking. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
Alerts. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
Saving history . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
Closures. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
Property list serialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
Challenge. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
Key points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
Chapter 10: Refining Your App. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
Neumorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
Creating a neumorphic button . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
Styles. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
Abstracting your button. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
The embossed button . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
@ViewBuilder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
ViewBuilder container view. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
Designing WelcomeView. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
raywenderlich.com 7
SwiftUI Apprentice
Gradients. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
Challenge. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
Key points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
Chapter 11: Understanding Property Wrappers. . . . . . . . . . . 277
Getting started. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
Tools for managing data. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
Managing UI state values. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
Accessing environment values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
Managing model data objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
Wrapping up property wrappers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
Key points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297
Chapter 12: Apple App Development Ecosystem. . . . . . . . . . 298
A brief history of SwiftUI. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
SwiftUI vs. UIKit. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
Apple Developer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
Housekeeping & trouble-shooting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
Key points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
Section II: Your second app: Cards. . . . . . . . . . . . . . . . 321
Chapter 13: Outlining a Photo Collage App. . . . . . . . . . . . . . . . 322
Initial app idea. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323
Creating the project. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
Creating the first view for your project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
Refactoring the view . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
Navigation toolbar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
Challenge. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
Key points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
Chapter 14: Gestures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346
Creating the resizable view . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
Creating transforms. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348
raywenderlich.com 8
SwiftUI Apprentice
Creating a drag gesture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
Creating a rotation gesture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
Creating a scale gesture. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
Creating custom view modifiers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
Other gestures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366
Type properties. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367
Creating global defaults for Cards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369
Challenge. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372
Key points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373
Where to go from here?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373
Chapter 15: Structures, Classes & Protocols. . . . . . . . . . . . . . . 374
Data structure. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
Value and reference types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376
Swift Dive: Structure vs class. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377
Creating the card store. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
Class inheritance. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379
Protocols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381
The preview data. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383
Listing the cards. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385
Understanding State and Binding property wrappers . . . . . . . . . . . . . . 395
Deletion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400
Challenge. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403
Key points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
Where to go from here?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
Chapter 16: Adding Assets to Your App. . . . . . . . . . . . . . . . . . . . 405
The starter project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406
Asset catalog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406
Launch screen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
Adding sticker images to your app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416
Reference folders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419
Using lazy grid views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428
raywenderlich.com 9
SwiftUI Apprentice
Challenges. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433
Key points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434
Where to go from here?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434
Chapter 17: Interfacing With UIKit . . . . . . . . . . . . . . . . . . . . . . . . 435
UIKit. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
Using the Representable protocols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
UIKit delegate pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438
Picking photos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439
NSItemProvider. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 442
Adding PhotoPicker to your app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444
Drag and drop from other apps. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446
Challenge. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452
Key points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453
Chapter 18: Paths & Custom Shapes. . . . . . . . . . . . . . . . . . . . . . . 454
The starter project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454
Shapes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455
Paths. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457
Strokes and fills. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465
Clip shapes modal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467
Associated types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468
Shape selection modal. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 472
Add the frame picker modal to the card. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473
Challenges. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476
Key points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478
Chapter 19: Saving Files. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479
The starter project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 480
The saved data format. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 480
When to save the data. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481
JSON files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484
Codable. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484
raywenderlich.com 10