
About this Book
Swift is a young language. At the time of writing, Swift has reached the fifth version and only recently turned ABI-stable. So why is this book in any position to tell you how to write your code?
You’d be right to be skeptical, but please bear with me. Even though Swift is relatively new, I think it’s fair to say that some solutions work better than others, which is even more essential to understand if you’re using Swift for real production apps.
Swift borrows a lot of important concepts from other programming languages, such as Haskell, Ruby, Rust, Python, C#, and others. Therefore, you’d be wise to keep an eye out for these concepts.
By mixing programming paradigms with real-world experience, this book shares some very fun and useful best practices you can instantly apply to your work.
Having programmed for over a decade in multiple languages and teams, I would like to share tips, tricks, and guidelines that helped my Swift career tremendously, and I want the same for you.
Honestly, a lot of software in this world runs on “ugly” code, and that is completely normal. If your product does what it needs to do, that is—like it or not—good enough for businesses.
As a developer, you have to make sure your product works and works well. But your users won’t look under the hood and point out ugly if statements. Perfectionism is harmful to software development and the cause to large numbers of unfinished projects.
Still, there’s a large gap between “It does what it needs to do” and a project where some excellent decisions were made that pay off in the long run.
Having worked on numerous projects, one thing I highly value is writing code that your coworkers and your future self will understand clearly—because elegant code means less chance of bugs, higher maintainability, better understanding for developers who inherit code, increased programmer happiness, and many other benefits.
Another aspect I value is the robustness of code, meaning how refactor-proof some pieces are. Will it break if you sneeze on it? Or can you change code without a hassle?
In this book, I share my tips, tricks, and guidelines that have worked well for me and companies I’ve worked for. On top of that, it fills in significant knowledge gaps that may arise while working with Swift.
Although this is a Swift book, a lot of the principles shared here are not Swift-centric and carry over to other programming languages as well; this is because Swift borrows a lot of ideas and paradigms from other languages. After you finish this book, you may find it easy to apply concepts in other languages. For instance, you’ll learn a lot about optionals, or how to use the reduce method on arrays. Later, you may decide to learn Kotlin, where you may apply optionals and reduce—called fold—straight away. You may also find Rust—and its similar generics implementation—easier to learn.
Because of Swift’s multi-paradigm nature, this book switches without preference between object-oriented programming, functional programming, and protocol-oriented programming paradigms—although admittedly, I do favor other techniques over subclassing. Switching between these paradigms offers you many tools and solutions to a problem, with insights as to why a certain solution works well or not. Whether you’re stuck in a rut or open to many new programming insights, this book challenges you to solve problems in different ways.
This book does assume that you have made one or more applications in Swift. Do you work in a team? Even better—this book shows you how to write good, clear code that gets appreciated in teams, and helps you improve pull requests of others. Your code will be more robust and cause less maintenance for you and your team.
This book fills in knowledge gaps for both beginner and seasoned Swift developers. Perhaps you mastered protocols but still struggle with flatMapping on types or asynchronous error handling. Or maybe you create beautiful apps but stay away from generics because they can be hard to interpret. Or perhaps you sort-of know when to use a struct versus a class but aren’t aware that enums are sometimes a better alternative. Either way, this book helps you with these topics. By the end, generics should come as naturally as for loops. You’ll be confident calling flatMap on optionals, know how to work with associated types, and you’ll gladly use reduce in your daily routine when working with iterators.
If you’re aiming to get a programming interview for a new job in the future, you’re in for a treat. You’re going to be able to answer a lot of relevant questions in regard to Swift development trade-offs and decisions. This book can even help you write elegant code in your code assignments.
If you just want an app in the app store, just keep doing what you’re doing; no need to read this book! But if you want to write code that is more robust, easier to understand, and increases your chances of getting a job, getting better at your job, or giving qualitative comments on pull requests, you’re at the right place.
This book is focused on Swift. It mostly uses framework-free examples because it isn’t about teaching Cocoa, iOS, Kitura, or other platforms and frameworks.
What does happen in this book is I often make use of Apple’s Foundation, which is hard to avoid if you want real-world examples. If you’re on Linux, you can use swift.org’s Foundation alternative to get similar results.
This book is very practical, showcasing tips and tricks you can apply straight away in your daily programming.
Don’t worry: it’s not a theory-dense book. You’ll learn a lot of theory, but only via the use of real-world problems that any Swift developer runs into sooner or later. It doesn’t, however, reach an academic level where it discusses Swift’s LLVM representation or machine code.
Also, I made sure to avoid a personal pet peeve of mine: I do not subclass “Animal” with “Dog” or add a “Flyable” protocol to “Bird.” I also don’t add “Foo” to “Bar.” You’ll deal with real-world scenarios, such as talking to APIs, loading local data, and refactoring and creating functions, and you’ll see useful bits and pieces of code you can implement in your projects.
The following sections provide an overview of the book, divided into chapters. The book is quite modular, and you can start with any chapter that interests you.
Some chapters I consider crucial chapters. Chapter 4, “Making optionals second nature,” is key, because optionals are so prevalent in Swift and return over and over again in chapters.
To understand the abstract side of Swift, I highly recommend reading chapter 7, “Generics,” chapter 8, “Putting the pro in protocol-oriented programming,” and chapter 12, “Protocol extensions.” Together, these chapters lay a solid foundation for key Swift skills. Be sure not to skip these!
As a bonus, if you’re interested in learning functional programming techniques, direct your attention to chapter 2, “Modeling data with enums,” chapter 10, “Understanding map, flatMap, and compactMap,” and chapter 11, “Asynchronous error handling with Result.”
highlight, annotate, and bookmark
You can automatically highlight by performing the text selection while keeping the alt/ key pressed.

This warmup chapter shows the current state of Swift, what it’s good at, what it’s not so good at, and what you’ll be doing in this book. It’s not very technical, but it sets expectations and prepares you for what you’ll learn.
discuss

This chapter is excellent if you want to flex your brain and think differently about modeling data and see how far enums can go to help you.
You’ll see how to model data with structs and enums, and how to reason about it so that you can turn structs into enums and back again.
You’ll be challenged to step away from the usual class, subclass, and struct approach and see how to model data with enums instead, and why you would want to.
You’ll also see other interesting uses for enums and how to use enums to write safer code.
By the end of this chapter, you may catch yourself writing enums a lot more.
settings

Swift has a rich property system with many options to pick from. You’ll learn to pick the right type of properties for the right types of situations. You’ll also create clean computed properties and stored properties with behavior.
Then you’ll discover when to use lazy properties, which can cause subtle bugs if they’re not carefully handled.
highlight, annotate, and bookmark
You can automatically highlight by performing the text selection while keeping the alt/ key pressed.

This chapter leaves no stone unturned regarding optionals.
Optionals are so pervasive that this chapter takes a very thorough look at them. Both for beginners and Swift masters, this chapter is riddled with best practices and tips and tricks that will boost your day-to-day Swift code.
It covers optionals in many scenarios, such as when handling optional Booleans, optional strings, optional enums, implicitly unwrapped optionals, and force unwrapping.
discuss

Life in the programming world starts with initializers. Avoiding them in Swift is impossible, and of course, you work with them already. Still, Swift has a lot of weird rules and gotchas regarding structs and classes and how their properties are initialized. This chapter uncovers these strange rules to help you avoid boxing matches with the compiler.
It isn’t just theory either; you’ll see how you can write less initialization code to keep your codebase clean, and you’re going to gain an understanding of subclassing and how the initializer rules apply there.
settings

Take our tour and find out more about liveBook's features:
- Search - full text search of all our books
- Discussions - ask questions and interact with other readers in the discussion forum.
- Highlight, annotate, or bookmark.
This book has two error handling chapters covering two different idioms: one for synchronous error handling, and one for asynchronous error handling.
This chapter deals with synchronous error handling. You’ll discover best practices related to throwing errors, handling errors, and maintaining a good state in your programs. But it also touches on propagating, adding technical information, adding user-facing information, and bridging to NSError.
You’ll also find out how to make your APIs a bit more pleasant by making them throw fewer errors while respecting the integrity of an application.
highlight, annotate, and bookmark
You can automatically highlight by performing the text selection while keeping the alt/ key pressed.

Generics are a rite of passage for Swift developers. They can be hard to understand or work with at first. However, once you’re comfortable with them, you’ll be tempted to use them often. This chapter makes sure you know when and how to apply them by creating generics functions and types.
You’ll see how you can make code polymorphic with generics so that you’ll be able to write highly reusable components and shrink down your codebase at the same time.
Generics become even more interesting when you constrain them with protocols for specialized functionality. You’ll discover core protocols, such as Equatable, Comparable, and Hashable, and see how to mix and match generics with them.
Generics won’t be intimidating after you have read this chapter, I promise.
discuss

Protocols—similar to typeclasses in Haskell or traits in Rust—are the holy grail of Swift. Because Swift can be considered a protocol-oriented language, this chapter provides a look at applying protocols in useful ways.
It covers generics and shows how they fare against using protocols as types. You’ll be able to clearly choose (or switch) between either. Protocols with associated types can be considered advanced protocols. This chapter makes sure that you understand why and how they work so that you don’t have to refrain from using them. It models a piece of a program with protocols, and keeps running into shortcomings, which it ultimately solves with associated types.
Then you’ll see how to pass protocols with associated types around in functions and types, so that you can create extremely flexible, yet abstract code.
This chapter puts a lot of focus on how to use protocols at compile time (static dispatch) and how to use them at runtime (dynamic dispatch) and their trade-offs. This chapter aims to provide a strong foundation for protocols so that you can tackle more difficult patterns in later chapters.
settings

It’s not uncommon to create a data structure in Swift that isn’t only using the core types, such as sets arrays and dictionaries. Perhaps you’ll need to create a special caching storage, or maybe a pagination system when downloading a Twitter feed.
Data structures are often powered up by the Collection protocol and the Sequence protocol. You’ll see how Sequence in turn is using the IteratorProtocol. With these combined, you’ll be able to extend and implement core functionalities in your data types.
First, you’ll take a look at how iteration works with the IteratorProtocol and Sequence protocols. You’ll discover some useful iterator patterns, such as reduce(), reduce(into:), and zip, as well as how lazy sequences work.
You’ll create a data structure called a bag, also known as a multiset, using the Sequence protocol.
Then you’ll discover the Collection protocol and the landscape of all the collection protocols Swift offers.
At the end, you’ll create another data structure and see how to make it conform to the Collection protocol. This part is highly practical, and you can apply the same techniques to your code straight away.
highlight, annotate, and bookmark
You can automatically highlight by performing the text selection while keeping the alt/ key pressed.

This chapter highlights key concepts commonly found not only in Swift but also other frameworks and programming languages.
Sooner or later you’ll run into map, flatMap, and compactMap on arrays, optionals, error types, and perhaps even functional reactive programming such as Combine.
You’ll get a proper look at how to clean up code by applying map and flatMap on optionals. But you’ll also see how to map over dictionaries, arrays, and other collection types. You’ll also learn the benefits of flatMapping over strings.
Lastly, you’ll get to review compactMap and how it elegantly handles optionals in collections.
Understanding map, flatMap, and compactMap on a deeper level is a good base for understanding how to read and write more concise yet elegant code, and a good base for working with Result in chapter 11.
discuss

Take our tour and find out more about liveBook's features:
- Search - full text search of all our books
- Discussions - ask questions and interact with other readers in the discussion forum.
- Highlight, annotate, or bookmark.
Swift’s regular error handling falls a bit short on asynchronous error handling. You’re going to take a closer look and see how to get compile-time safety for asynchronous programming by making use of a so-called Result type, which is available since Swift 5.
Perhaps you’re using some version of Result already, found in multiple frameworks. But even if you’re acquainted with Result, I’d wager that you’ll see new and useful techniques in this chapter.
You’ll start by learning the downsides of traditional Cocoa-style error handling and why Result can help with that.
Also, you’re going to take a look at transforming throwing functions to Result and back again. You’ll see how to avoid NSError and how Result offers a lot of compile-time safety. However, if the rigid structure of Result is not your cup of tea, then we’ll look at alternatives using a special trick that Swift 5’s Result offers regarding dynamic errors.
As a cool trick, you’ll learn about the Never type, which is a unique way to tell the Swift compiler that a Result can never succeed or fail.
Lastly, you’ll use what you learned from map and flatMap on optionals to understand how to map over values and errors, and even how to do advanced error handling and error recovery, using flatMap and flatMapError on Result. You’ll end up with a so-called monadic style of error handling, which gives you the power to very cleanly and elegantly propagate an error up in the call stack with very little code while keeping a lot of safety.
settings

This chapter is all about modeling data in a decoupled way, offering default implementations via protocols, making use of clever overrides, and seeing how to extend types in interesting ways.
As a start, you’ll learn about modeling data with protocols versus subclasses.
Then, you’re going to model data two ways: one approach entails protocol inheritance, and the other uses protocol composition. Both have their pros and cons, which you’ll discover when you go over the trade-offs.
Also, you’ll see how protocol extensions work when overridden by protocol inheritance and concrete types. It’s a little theoretical, but it’s useful to understand protocols on a deeper level.
You’ll also see how you can extend in two directions. One direction is extending a class to adhere to a protocol, and the other is extending a protocol and constraining it to a class. It’s a subtle but important difference.
At the end of the chapter you’re going to extend Collection, and then you’ll dive deeper and extend Sequence to create highly reusable extensions. You’ll get acquainted with ContiguousArray and functions that have the rethrows keyword, while you create useful methods you can directly apply in your projects.
highlight, annotate, and bookmark
You can automatically highlight by performing the text selection while keeping the alt/ key pressed.

This may be the hardest chapter in the book, but it’s a great mountain to climb.
This chapter’s goal is to handle common obstacles that you may run into. The patterns described here are not a rehash of SOLID principles—plenty of books cover that! Instead, it focuses on modern approaches for a modern language.
You’ll discover how to mock an API with protocols and associated types—something that comes in handy frequently—so that you can create an offline version of an API and a testing version of an API.
Then, you’ll see how conditional conformance works in accordance with generic types and protocols with associated types. Next, you’ll create a generic type, and power it up by using the powerful technique of conditional conformance, which is another way to deliver highly flexible code.
After that, you’ll deal with an issue you may run into when trying to use a protocol as a concrete type. You’ll use two techniques to combat it: one involves enums, and the other involves an advanced technique called type erasure.
Lastly, you’re also going to examine whether protocols are a good choice. Contrary to popular belief, protocols are not always the answer. You’ll look at an alternative way to create a flexible type, involving a struct and higher-order functions.
discuss

This is the least code-centric chapter in the book, but it may be one of the most important ones.
It’s about writing clean, easy-to-understand code that creates fewer headaches for everybody on your team (if you’re on one). It challenges you about establishing naming conventions, adding documentation and comments, and cutting up large classes into small generic components. You’ll also set up SwiftLint, a tool that adds style consistency and helps avoid bugs in your projects. Also you’ll get a peek at architecture, and how to transform large classes with too many responsibilities into smaller generic types.
This chapter is a good check to see if your code is up to standards and styles, which will help when creating pull requests or finishing code assignments for a new job.
settings

At this point, your Swift skills will be seriously powered-up. I share some quick pointers on where to look next so you can continue your Swift journey.
This book contains many examples of source code, both in numbered listings and in line with normal text. In both cases, source code is formatted in a fixed-width font like this to separate it from ordinary text. Sometimes code is also in bold to highlight code that has changed from previous steps in the chapter, such as when a new feature adds to an existing line of code.
In many cases, the original source code has been reformatted; we’ve added line breaks and reworked indentation to accommodate the available page space in the book. In rare cases, even this was not enough, and listings include line-continuation markers (). Additionally, comments in the source code have often been removed from the listings when the code is described in the text. Code annotations accompany many of the listings, highlighting important concepts.
The source code for all listings in this book is available for download from the Manning website at https://www.manning.com/books/swift-in-depth and from GitHub at https://github.com/tjeerdintveen/manning-swift-in-depth. With the exception of chapters 14 and 15, every chapter has source code included.
Purchase of Swift in Depth includes free access to a private web forum run by Manning Publications where you can make comments about the book, ask technical questions, and receive help from the authors and from other users. To access the forum, go to https://forums.manning.com/forums/swift-in-depth. You can also learn more about Manning’s forums and the rules of conduct at https://forums.manning.com/forums/about. Manning’s commitment to our readers is to provide a venue where a meaningful dialogue between individual readers and between readers and the authors can take place. It is not a commitment to any specific amount of participation on the part of the authors, whose contribution to the forum remains voluntary (and unpaid). We suggest you try asking the authors some challenging questions lest their interest stray! The forum and the archives of previous discussions will be accessible from the publisher’s website as long as the book is in print.
Tjeerd in ’t Veen is an avid Swift fan and a freelance iOS developer, having experience working for agencies, co-founding a small startup, and at time of writing, helping ING scale up their mobile development. Starting out as a Flash developer in 2001, his career progressed to iOS development with Objective-C, web development with Ruby, and some tinkering in other programming languages.
When he’s not developing in Swift, he’s busy spending time with his two daughters, making cringy dad jokes, and dabbling on an acoustic guitar.
You can find him on Twitter via @tjeerdintveen.
The figure on the cover of Swift in Depth is captioned “Man from Omišalj, island Krk, Croatia.” The illustration is taken from the reproduction, published in 2006, of a nineteenth-century collection of costumes and ethnographic descriptions entitled Dalmatia by Professor Frane Carrara (1812–1854), an archaeologist and historian, and the first director of the Museum of Antiquity in Split, Croatia. The illustrations were obtained from a helpful librarian at the Ethnographic Museum (formerly the Museum of Antiquity), itself situated in the Roman core of the medieval center of Split: the ruins of Emperor Diocletian’s retirement palace from around AD 304. The book includes finely colored illustrations of figures from different regions of Dalmatia, accompanied by descriptions of the costumes and of everyday life.
Dress codes have changed since the nineteenth century, and the diversity by region, so rich at the time, has faded away. It is now hard to tell apart the inhabitants of different continents, let alone different towns or regions. Perhaps we have traded cultural diversity for a more varied personal life—certainly for a more varied and fast-paced technological life.
At a time when it’s hard to tell one computer book from another, Manning celebrates the inventiveness and initiative of the computer business with book covers based on the rich diversity of regional life of two centuries ago, brought back to life by illustrations from collections such as this one.
In this book
Acknowledgements Index List of Figures List of Listings