The Missing Manual For Swift Development Bart Jacobs

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 269

DownloadThe Missing Manual For Swift Development - Bart Jacobs
Open PDF In BrowserView PDF
The Missing Manual for Swift Development

Bart Jacobs

This book is for sale at http://leanpub.com/the-missing-manual-for-swiftdevelopment
This version was published on 2017-09-27

*****
This is a Leanpub book. Leanpub empowers authors and publishers with
the Lean Publishing process. Lean Publishing is the act of publishing an
in-progress ebook using lightweight tools and many iterations to get
reader feedback, pivot until you have the right book and build traction
once you do.
*****

© 2017 Code Foundry BVBA

Table of Contents
Welcome

Part 1: Foundation
1 Your Foundation
What Is Your Foundation
There Is No Clear Path

2 Where to Start
Setting Yourself Up for Success
A Path Without Distractions
Choose Your Teacher Wisely

3 Know Your Tools
Xcode
Developer Portal
Provisioning
Instruments
Command Line
Third Party Tools

4 Adopt Best Practices
What Are Best Practices
Patterns
Anti-patterns
Good Practices for Swift
Be Critical

5 Security
Make It Hard
Plain Text
Obfuscating Information
Fetching Sensitive Information
Encryption
Privacy
Logging and Debugging
Educating Your Client

6 Don’t Ignore Your Foundation
Under the Hood
Dependencies
Don’t Ignore the Fundamentals

7 Respect the SDK
Know Your Limitations
Respect the SDK

9 Design Patterns
Model-View-Controller

Model-View-ViewModel
Singletons
Dependency Injection
References, Delegation, and Notifications
Master These Patterns
6 Protocol-Oriented Programming
7 Reactive Programming

Part 2: Swift
1 Learn Swift With an Open Mind
Reference Types and Value Types
Protocol-Oriented Programming
Type Safety
Best Practices
Forget What You Know

2 Be Critical
3 Embracing Optionals
Warning Sign
Elegance and Beauty
Swift to the Rescue
Embrace Optionals

4 Mind the Exclamation Mark
Use Cases
Convenience and Laziness
Don’t Be Lazy
When I Use the Exclamation Mark
A Personal Choice

5 Exclamation Marks and Fatal Errors
Clarity Over Subtleness
Choosing for Clarity

6 Smelly Code
Forced Unwrapping and Conversion
Monster Classes
Massive Methods
Ignoring Errors
Singletons
String Literals
Is Your Code Smelly

7 Value Types and Reference Types
What’s the Fuss
An Example
Benefits of Value Types
When to Use Value Types

8 Catching Errors
When Should You Handle Errors
Where Should You Handle Errors

Notifying the User
Monitoring Application Health
Don’t Ignore Them

9 Using Fatal Errors to Write Elegant Swift
What to Do When You Don’t Know What to Do
Guarding Against Unexpected Events
Use Fatal Errors Sparingly
Clarity and Elegance

Part 3: Projects
1 A Brand New Project
Step 1: Setting Up the Project
Step 2: Organizing the Project
Step 3: Adding a README.md
Step 4: Build and Run
Step 5: Adding a .gitignore
Step 6: Putting the Project Under Source Control
Step 7: Pushing the Project to GitHub
Step 8: Optional Steps

2 Project Structure
An Example
View Controllers
Test Target
On Disk
What Do I Gain
Tools
Caveats

3 Project Hygiene
Projects Evolve
Obsolete Files
Comments
Documentation
Don’t Commit Everything
Guidelines and Exceptions

4 Document Everything
Start With the Basics
Make It Easy
What to Document
Up to Date
Make It a Core Tool
I’m a Team of One
Make It a Habit
Time Is Money

Part 4: Workflow
1 Testing

Where to Start
Code Coverage
Writing Better Code
Dependency Injection
Xcode and Testing
My Current Test Setup
What Are You Testing
It Takes Time

2 Continuous Integration
What Is It
Why Is This Useful
Long Hanging Fruit
Avoid Human Tinkering
TestFlight
Painless Releases
Make It Robust
Transparency
Learning Curve

3 Refactoring
Technical Debt
Building for the Future
The Fallacy of Sunk Cost
Starting Anew

4 Source Control
The Basics
Don’t Break These Rules
Commits
Stashing
Patching
Git Flow
Some Tips

5 Dependencies
Minimize Dependencies
What Is a Dependency
Fewer Dependencies
Mapping the Liabilities of a Project
Don’t Make Your Life Too Easy
Rolling Your Own
Choose Wisely
Becoming a Better Developer
Watch Out for the Defaults
Challenge Yourself

6 Automation
Scripting
Build Phases
Automated Testing
Documentation
Continuous Integration

fastlane
Keep It Simple

7 Privacy
Protecting the User’s Privacy
Who Do You Work With
Giving the User Control
Third Party SDKs
Choose Wisely

8 What to Do When You Inherit a Software Project
First Things First
Build and Run
Collect Data
Dependencies
Working on the Project
Document Everything
And Beyond

9 Speed, Quality, and Technical Debt
Speed and Quality
Technical Debt
Focus
How to Get Rid of Technical Debt
Taking Shortcuts

Part 5: Team
1 Code Reviews
Just Start
Calendar and Agenda
Make Them Actionable
Keep Them Small
Be Prepared
Tools
That Hurts
Convincing Management
Frequency
But It’s Just Me
Give It a Try

2 Adopt a Style Guide
Why Have One
Automation
Rough Transition

3 Working In a Team
Hire the Right People
Leadership
Communication
Give It Time
Respect
When Things Hit the Fan

Ownership and Responsibility
Share and Ask

4 Being a Leader
Listen and Be Open
Modesty, Humility, and Respect
Work as a Team
Working With People
Follow Your Gut
Lead

Part 6: Career
1 Open Source
Start Small
Taking the Plunge
Documentation
Taking It Seriously
Giving Up Control
Taking Responsibility

2 You Are the Constant in Your Career
Putting Yourself First
Setting Goals
Learning Requires an Investment
Take Care of Yourself
Looking Back

3 Build That Application
Build and Ship
Show What You Can
Stay Ahead
Rinse and Repeat
Build That Application

4 Protect Your Productivity
Working From Home
Working In an Office
Minimizing Interruptions
Find a Quiet Place
Deal With It

5 Building Your Portfolio
Scratch an Itch
Setting Goals
Learn the Basics
But Start Creating

6 How Badly Do You Want It
Contribute
Build
Maintain
Plan and Manage

Gain Experience
Be Yourself
How Badly Do You Want It
What About You

7 Freelancing and Subcontracting
Freelancing and Subcontracting
Being Picky
Firing Clients

Part 7: Products
1 Ship, Ship, Ship
It’s Hard
How to Ship Consistently
Internal Deadlines
Remove Friction and Clutter

2 Talk to Your Customers
Solve a Problem
Ground Zero
Is This for You
But It’s Fantastic
A Recipe for Success

3 What Is Stopping You From Shipping
Why Is This Important
Start Small
Remove Clutter

4 Motivation Will Get You Only Halfway
Motivation Won’t Cut It
Running a Marathon
Pulling the Plug
Start and Persevere
Challenge Yourself

5 How to Make a Living as a Mobile Developer
Paid Up Front
Freemium
Advertising
In-App Purchases
Subscriptions
Donations
Finding the Right Business Model
Experiment But Be Smart
Evolution

Part 8: You
1 Being and Staying Productive
Maintaining Focus
Protect Your Productivity

Distraction Is Addictive
Take Care of Yourself

2 Stop Looking for the Silver Bullet
An Example
Investigate and Test
Stop Looking for the Silver Bullet

3 You Are Not an Imposter
What Is It
Why Do I Bring This Up
Curing Imposter Experience
Talk About It
It’s Common
Don’t Believe Everything You Read
Don’t Let It Affect You
Success Through Failure

Part 9: Learning
1 Choose Your Teacher Wisely
Information Overload
Who to Trust
Focus, Focus, Focus
Never Stop Learning

2 Taking a Shortcut
Internship
Freelancing and Subcontracting
Learn, Learn, Learn
Build, Build, Build
Choose Wisely

3 Some Things Are Hard
Cut Yourself Some Slack

4 Learn the Rules, Then Break Them
Examples
Growing as a Developer
Creating Something Better

Welcome
The title of my book, The Missing Manual for Swift Development,
accurately describes what I have in store for you. It’s the guide I wish I
had when I started out as a software developers years and years ago.
The Missing Manual for Swift Development is a summary of what I’ve
learned over the years building software for Apple’s ecosystem. Many of
the lessons in my book I learned from experts in their field and,
unfortunately, just as many I learned the hard way. I hope that some of
the topics in this book can help you on your way to become remarkable in
what you do. That’s your goal. Is it not?
Writing a few lines of Swift is surprisingly easy. Once you start to dig
deeper, though, you discover that building an application for Apple’s
ecosystem is more challenging than it seems. The Missing Manual for
Swift Development outlines the challenges you face along your journey
and how to overcome them.
Some of the more obvious topics I cover include dependency
management, source control, code reviews, continuous integration, style
guides, working in a team, tooling, project organization and
documentation, and release strategies.
The topics I found most interesting to write about, however, are more
meta, such as when to break the rules, freelancing and subcontracting,
staying productive as a developer, shipping projects, leaving your comfort
zone, and dealing with challenging problems.
My book doesn’t include many code snippets or sample projects. The
goal of this book is to provide insights and answers to questions that are
often overlooked or ignored.
The Missing Manual for Swift Development is for every type of
developer, but it primarily focuses on Swift and Cocoa development. If

you’re developing for Apple’s ecosystem, then you’ll find a lot of useful
information, regardless of your experience.
There are very few shortcuts in software development. You pay a price
for most of the shortcuts you read about, one way or another. But there
are a handful of shortcuts that can speed up your learning and your
career. A proper education is one of them.
I hope that my book helps you in some way, big or small. If it does, then
let me know. I’d love to hear from you.
Enjoy,
Bart

PART 1: FOUNDATION

1 Your Foundation
Developers that come to Apple’s platforms have many different
backgrounds, and some of us are better prepared than others.
Regardless of your background, though, you can make sure that you’re a
good fit for Apple’s ecosystem by investing in your foundation. That’s the
subject of this chapter.
This may sound boring at first, and for some it is boring, but it’s essential
if you plan to create robust, scalable applications and if you want to have
a long career in the mobile space.
There’s a slew of reasons why developers are drawn to Apple’s
ecosystem. Many of us make the jump because of the shiny stuff. ARKit
and Core ML are good examples of what I like to refer to as shiny stuff.
Both are amazing technologies, and I’m sure you’ve seen stunning
examples of developers taking advantage of ARKit. ARKit and Core ML
are the cherries on the cake. And the cake is your foundation. Without
the cake, there are no cherries.

What Is Your Foundation
The foundation is what happens to interest me most. It isn’t as compelling
or visually stunning as ARKit, but it’s essential for every single
application. Not only is that why it’s so important, but that’s also why it’s
worth investing time in your foundation. It pays dividends for a long time.
Let’s start with the language.

Swift
As a Swift developer, the first component of your foundation should be
the language you use day in day out. Swift. Since you’re reading this, I’m
going to assume that you already have a good grasp of the Swift
language or, at a minimum, you’ve browsed The Swift Programming
Language and you’ve written a handful of lines in a playground.

I’m sure I don’t need to convince you of the importance of knowing and
understanding the Swift language. How are you going to write a fantastic
novel if you don’t master the language the novel is written in? Why would
this be any different for software development?
But this doesn’t mean you need to spend days, weeks, or months
learning the Swift language. I recommend a different approach that’s
more fun and more practical. I don’t like spending hours or days learning
a new library, framework, or API. I learn best by applying what I read and
learn. The same is true for the Swift language.
Start with the basics and use it. You can pick up the basics of any
language in no time. But, as with any language, you only get what you’ve
learned by applying it. That means writing Swift. You can use Swift in a
playground or start with a simple Cocoa application. Apple did a fantastic
job by introducing playgrounds alongside the unveiling of the Swift
language. Use them. Launch Xcode, create a playground, and play with
Swift.
Optionals

Many developers will go through a phase in which they struggle with the
language. That’s fine. Let yourself be frustrated for a while. It’s natural,
and it means that you’re noticing aspects of Swift that are core to the
language. Be skeptical and ask questions.
Based on conversations with students and readers, optionals are one of
the most common obstacles developers need to overcome. I genuinely
love optionals, but I too was frustrated when they first crossed my path.
This wasn’t surprising considering my background in Objective-C. As you
probably know, Objective-C isn’t as strict about nil pointers. Dealing with
nil is an entirely different story when you’re writing Swift.
If you’re still struggling with optionals or don’t see how they fit in the
language, then I need to ask you to trust the language for now. It will click
at some point, but you need to embrace optionals. Don’t use the
exclamation mark to plow your way through a forest of optionals.
Optionals are an integral part of the language and an essential
component of one of Swift’s key features, safety.
Step Up Your Game

The more you use the language, the more you start to appreciate it. What
I tend to do is gradually add more complexity to the code I write. Learn
about value types and reference types. Discover what protocols are and
why they’re useful. You may want to explore generics at some point. Take
a close look at enumerations and find out why they’re so much more
powerful than their Objective-C counterparts.
If you think you know the Swift language, then I recommend taking
another look at The Swift Programming Language. Every time I read
Apple’s guide, I learn something new. Most of the times, I can directly
apply it to the code I write day to day. I love it. Swift was designed to be
more expressive, and it feels richer than Objective-C. That’s something
you can and should take advantage of in the code you write.

Concepts
Even if you still use Objective-C, there are concepts that you need to
know about, regardless of the language you use. These concepts are
often scary to new developers, such as memory management,
asynchronous programming, and grand central dispatch. These are
concepts and technologies that are often ignored or overlooked.
Unfortunately, this leads to memory leaks, crashes, and a lot of
frustration.
This frustration often leaves a bad taste in your mouth, and it can even
affect your fondness for the language and the platform. There’s nothing
as frustrating as debugging an issue caused by something you don’t fully
understand. It happened to me many times, and it simply isn’t fun. It pays
off to invest time in learning the ins and outs of these fundamentals. I talk
more about this later in the book.

SDK
You can do quite a bit with the Swift language that doesn’t involve Apple.
The language is available on Linux, and there are several frameworks
that you can use to build web APIs powered by Swift. There are also a
number of tools and libraries you can use to write scripts using Swift,
such as Marathon, Rainbow, and Commander.

But most of us use Swift to power mobile or desktop applications, which
means we need to become familiar with a bunch of tools, frameworks,
and libraries. The most common ones are Foundation, the bread and
butter of every Cocoa developer, UIKit and AppKit, and several other
ones, such as Core Data, AVFoundation, CloudKit, and HealthKit. The
time you spend exploring and learning about these frameworks and
libraries is time well spent.

Design Patterns
There are dozens and dozens of design patterns you can pick and
choose from and a handful of these design patterns are used by the
frameworks and libraries you use on a daily basis. At a minimum, you
need to know about and become familiar with these fundamental design
patterns. Let me give you a quick overview of the most important ones.
Later in this book, I zoom in on a few of these design patterns.
Model-View-Controller

The first design pattern you inevitably come into contact with when you
create your first project in Xcode is the Model-View-Controller pattern.
It’s this pattern that powers most Cocoa applications. If you’ve been
reading Cocoacasts for a while, then you know that I’m not a raving fan of
this design pattern. It falls short in a number of ways, and I mostly use
the Model-View-ViewModel pattern instead.
The Model-View-Controller pattern is easy to pick up, and it’s a good fit
for building Cocoa applications. Apple’s SDKs are impregnated with this
pattern and most of us have used the Model-View-Controller pattern for
years and years, and not only for building Cocoa applications. It’s a
widely used, versatile design pattern that has earned its stripes over
several decades.
Delegation

Another very common pattern you encounter in Apple’s frameworks and
libraries is delegation. The concept is simple, and it promotes loose
coupling and code reusability. If you’ve used table views in your
application, then you’re already familiar with delegation. A table view isn’t
responsible for responding to user interaction. It delegates this task to a
delegate object. When a user taps a row in the table view, the table view

notifies its delegate about this event. It’s up to the delegate object, a view
controller, for example, to decide how the application should respond.
The data source pattern is similar. It’s used to populate a table view with
data. A table view is a pretty dumb object. That’s a good thing because it
promotes reusability. It asks its data source what data it needs to present
to the user. The table view only knows how to present the data it’s given
by its data source.
Notifications

While delegation is a good fit for objects that have a one-to-one
relationship, notifications are ideal for distributing messages to one or
more unrelated objects. Know and understand what the differences are.
Delegation and notifications aren’t interchangeable design patterns.
Like delegation, notifications are very common in Apple’s frameworks
and libraries. They’re an essential ingredient of every Cocoa application.
KVC and KVO

Key-value coding and key-value observing are related concepts that
power the Cocoa frameworks. Unfortunately, they’re almost always
overlooked by developers new to Cocoa. For that reason, I spend some
extra time discussing these concepts later in the book. Make sure you
don’t skip KVC and KVO if you’re not quite sure what they are.

Xcode
One of the first tasks you need to take care of if you decide to build a
Cocoa application is downloading, installing, and launching Xcode.
Developers rarely take the time to learn the ins and outs of Apple’s
powerful IDE (Integrated Development Environment). Spend some time
exploring the basics of Xcode. There are many, many tips, tricks, and
features you only pick up after using Xcode for a while, but it’s
nevertheless important to learn the basics.

There Is No Clear Path
We live in times where we’re bombarded with information. If you’re
learning a new technology, framework, or tool, you only need to enter a
few words into Google, and you’re presented with dozens if not hundreds

of resources, many of them free. The problem is that most of us struggle
with this abundance of information. Which resource should we choose?
How do we separate the good from the bad? Should I learn something
else first?
The mobile space is evolving at such a rapid pace that many of us are
scrambling to keep up. To be honest, I don’t feel that. The reason is
simple. I invest in my foundation, and that continues to pay dividends.
Learning a new framework with a solid foundation to rely on is much
easier. I can’t repeat this enough, invest in your foundation. Every. Single.
Day.
Once you have that foundation, everything automatically becomes easier.
You’ll notice that there’s nothing you cannot master. Apple’s
documentation no longer looks mysterious. It starts to make sense.

Focus
When Apple released the iPhone in 2007, we didn’t have an SDK to work
with. The more experienced developers among us reverse engineered
the operating system and built applications for the first iPhone. Ten years
later, Apple has given developers access to a rich ecosystem with the
tools we need to build amazing software. As a Cocoa developer, you can
build software for your computer, your phone, your tablet, your watch,
and even for your television. These are amazing times. But, again, it’s
easy to be overwhelmed. Focus is important.
I know several developers that build software for both Apple’s and
Google’s ecosystems. While this may seem appealing, it isn’t something I
recommend. It’s very challenging to stay up to date about one platform let
alone two. There certainly are advantages to this approach, but it’s more
important than ever to specialize.
Your attention is a valuable asset, and I recommend to focus, focus
aggressively. If your employer expects you to be up to date on iOS, tvOS,
macOS, and watchOS, then they’re expecting too much. Chances are
that they’re not technical or don’t know much about Apple’s ecosystem.
Gone are the days that you know every framework and library inside out.

I choose to focus on Apple’s ecosystem, with a strong emphasis on iOS. I
also build tvOS and watchOS applications, and the occasional macOS
application, but those aren’t my main focus. This focus allows me to build
robust, performant applications.
Apple applies that same focus, or it used to. Choosing a new Apple
computer used to be a simple task because you only had a handful of
options. While that’s no longer true, it emphasizes the power of focus and
simplicity. And it’s the reason I choose to build a career on Apple’s
ecosystem.

Which Path to Follow
The most common question, or frustration, I hear from developers new to
Cocoa and Swift is “Where should I start?” There’s so much to learn, or
that’s how it seems. You have the language, the tools, the frameworks,
the App Store. There doesn’t appear to be a clear path; there’s only a lot
of information. Platforms like Stack Overflow are fantastic, but it’s
important to learn to digest end-to-end information.
There doesn’t seem to be a clear path, there’s only a lot of
information.
I talk more about this later in the book, but I need to repeat myself by
saying that focus is essential. If you’re starting out as a developer, then
make sure you’re not jumping from topic to topic. Choose a proven path.
A resource I often recommend to developers is the book about Cocoa
development published by Big Nerd Ranch. It’s this book by Aaron
Hillegass that taught me Cocoa development. Aaron and his team have
decades of experience teaching people Cocoa development.
There are three reasons for choosing a trusted source. First, you learn
the fundamentals. Second, you can ignore the abundance of information
and focus. Third, you’re sure you’re learning things the right way. Big
Nerd Ranch, for example, has been around for almost two decades, an
eternity in the technology industry.
Focus, focus, focus. That’s what’s going to keep you sane in today’s
world. That’s one of the first things I teach the students I coach. It’s fine to

ignore most of what you read and focus on one thing at a time. Your
productivity will skyrocket, and your confidence will follow suit.

2 Where to Start
In this chapter, I describe the path I recommend to people that are new to
Cocoa and Swift development. If you’re new to programming, then I
recommend taking a basic course on programming first.
The path I present in this chapter requires you to learn a collection of
skills, patterns, and paradigms. Remember from the previous chapter
that it’s essential that you remain focused. It’s tempting to jump from topic
to topic because there’s a lot you need to learn.

Setting Yourself Up for Success
Before we explore the path to learn Cocoa and Swift development, it’s
important to understand that it takes time. Not only does it take time to
learn the various topics I cover in this chapter, it takes time to let
everything sink in.
You will encounter concepts that only click a day, a week, or a month
after you’ve read about them in a book or seen them explained in a
video. Don’t let yourself become frustrated if you don’t get everything
right away. That’s perfectly normal.
Don’t let yourself become frustrated if you don’t get everything right
away. That’s perfectly normal.
The Swift language is easy to pick up, but the finer details and more
advanced features are more challenging. The Cocoa SDK with its many
frameworks and APIs can seem daunting, but if you know what to focus
on when and understand why you’re learning something, then the pieces
of the puzzle start to fit together, showing you the bigger picture.

A Path Without Distractions
The path I almost always recommend to students new to Cocoa and
Swift development shows you how to build an application from start to

finish. I strongly believe that every developer needs to become familiar
with every step of building and deploying an application.
If you decide to work at a larger company as an employee, you probably
won’t have to deal with every step of this process. However, knowing
about and understanding the steps involved to build an application is an
integral part of your foundation. It’s essential that you understand every
step of the process, and there’s no better way to learn the steps than to
go through the process yourself.

Step 1: Learn the Language
The first step is the most obvious one, learning the Swift language.
Learning the language and the frameworks at the same time isn’t
something I recommend, unless you’re already familiar with Objective-C.
That’s why I always recommend to learn the basics of the Swift language
first. The Swift Programming Language is a very good starting point and
it’s what I recommend you read. If you’re new to Swift and Objective-C, I
recommend skipping A Swift Tour because it will confuse you more than
it will teach you.
The Swift Programming Language is available from the Swift website
and you can download it for free from iTunes. But don’t take the book and
read it from cover to cover. Take out your computer, install Xcode, and
write code. Let everything sink in by applying what you learn. You only
learn the language by writing it, using its syntax, and becoming familiar
with the various concepts. Write, write, write.
This also means it’s time to install Xcode. Visit the Apple Developer
website and download a copy of Xcode. You can also download Xcode
from the Mac App Store. Fire up Xcode, create a playground, and write
code as you read The Swift Programming Language. This is one of the
best approaches to learn the language.
I browse The Swift Programming Language several times a week.
Because it contains so much information, it’s virtually impossible to learn
and understand everything about the language after one read.
When is it time to continue to the next step? You’re ready to move on if
you understand the basics of the language. How do you know if you do?

It means that you understand and can apply the following concepts and
paradigms.
You understand the difference between variables and constants, and
you know when it’s appropriate to use which.
You know what optionals are, why they’re integral to the language,
and you also understand what the exclamation mark stands for. You
also need to understand optional chaining, safely unwrapping, and
the meaning of nil.
You understand and can use strings, arrays, dictionaries, and sets.
You also know about object literals and how to create them.
You can use control flow to add complexity to the code you write.
You understand the basics of functions and closures, and you can
use them.
You know what classes, structures, and enumerations are and what
sets them apart.
You understand what reference types and value types are, you know
the pros and cons of each, and you get what sets them apart.
You understand the basics of protocols. You can define a protocol
and create a type that conforms to that protocol.
You also know about extensions and how to use them.
You’ll learn a lot more along the way, such as error handling, inheritance,
properties and methods. You should now be ready to build your first
application.

Step 2: Build an Application
Once you have a basic understanding of the Swift language, it’s time to
start building something that runs on an iPhone or an iPad. Even though
playgrounds are fantastic to learn Swift, you started this journey to build
applications. One of the most exciting moments of my journey as a
software developer was the day I ran my first application on a physical
device.
I encourage you to create your first application as soon as you have a
good grasp of the language. The application won’t do much, but it puts
the language and the frameworks together. It should also get you excited

about what’s to come. There’s nothing as exciting as running your very
first application on your phone or tablet.

Step 3: Explore the SDK
The application you build in the previous step won’t make a dent in the
universe, but it whets your appetite. It’s time to become familiar with the
frameworks and tools you need to build robust applications, which
includes learning about the Foundation framework, the Swift standard
library, and UIKit (iOS) or AppKit (macOS). A good book or course on
Cocoa development covers the important aspects of these frameworks
and tools.
For iOS developers, it’s essential to be familiar with views and view
controllers. Understand how a view relates to a view controller and how
both fit into the Model-View-Controller pattern. While you could create the
user interface in code, I don’t recommend this. Apple pushes developers
to storyboards and that’s something you need to become familiar with.
But don’t ignore XIB files. They’re a fine alternative if you don’t like
working with storyboards.
Auto Layout is a layout engine that makes building user interfaces easier.
You need to become familiar with constraints, layout guides, and view
hierarchies. Don’t skip this step. Many developers do and pay the price
later.
Almost every iOS application includes a table view or a collection view.
As you learn how they work, you also pick up the delegation and data
source patterns, which we discussed in the previous chapter.
Navigation controllers are another essential ingredient of most iOS
applications. It may be challenging to wrap your head around the
concept, but once it clicks you’ll find them easy to use. The same applies
to tab bar controllers.
Storing data is a task of most applications. There are many solutions
available. The simplest solution provided by the Cocoa SDK is the
defaults system. The defaults system is nothing more than a key-value
store. You’ll find yourself using it very often. I also recommend learning

about more advanced types of data persistence, such as storing data in a
file on disk or in a database.
Later in this chapter, I emphasize how important it is to choose a
resource that teaches you these fundamentals. It pays to invest in a good
book or course. You’re investing in your foundation.

Step 4: More Challenges
After you understand the fundamentals covered in the previous step, it’s
time for a slight detour to learn about a few more advanced, yet essential,
aspects, including memory management, asynchronous programming,
and data persistence. These are more advanced topics, but you need to
learn them as they’re an ingredient of every application that has a bit of
complexity to it.
I repeat, pick a good book or course to learn these concepts. It’ll make
your journey that much easier. Memory management and multithreading
are not easy to grasp for an inexperienced developer. But believe me
when I say that you can do this.

Step 5: Build That Application
It’s time to accelerate your learning by building an application. This step
is the cherry on the cake. You start with an empty Xcode template and
start translating your idea to a functional product. It doesn’t matter what
idea you have but it needs to be challenging.
It doesn’t need to be unique, though. A good example is an application to
take notes or view the weather. The goal is to apply what you have
learned in the previous steps.
Be prepared. You will run into problems and you will need to learn some
more to finish the project. It will take you days or weeks to complete this
step. I hope this doesn’t scare you because that’s the reality of software
development.
If you’re a developer, then you’ll need to continue learning on a daily
basis. This is inevitable, especially in a space that moves a breakneck
speed.

Step 6: What About Testing
Testing is often skipped for some reason. If testing were a difficult
subject, I’d understand why that is. But it isn’t. I feel it’s usually skipped
because it isn’t a cool topic. Don’t skip this step. Testing isn’t as hard as
you think. Later in this book, we cover testing in a bit more detail.

Step 7: Publish
If your application is ready to be shared with the world, it’s time to publish
it on Apple’s App Store. This is quite challenging because you need to
use a bunch of tools to publish your application. You need to visit the
Developer Portal, provision your application, and prepare your application
in iTunes Connect. This isn’t rocket science, but it can be frustrating the
first time you try to use these tools. Don’t worry, though. You can do this
too.

Choose Your Teacher Wisely
While you can go through these steps on your own, I recommend that
you look for help. You can learn the Swift language by reading The Swift
Programming Language. Learning the Cocoa SDK is a bit more
challenging. That’s the step in which most developers lose track.
Pick up a book or course that covers the fundamentals in such a way that
you learn everything you need to build a simple yet functional application.
Later in this book I talk about the importance of choosing your teacher.
Make sure you learn from someone you trust. That someone teaches you
best practices and they also show you which practices to avoid. Your
teacher keeps you sane and confident as you learn your craft.
I can recommend anything published by Big Nerd Ranch, such as iOS
Programming: The Big Nerd Ranch Guide. That said, there are various
books and courses that are very good. Don’t pick any book or course.
Make sure you team up with someone who knows his or her stuff.
Don’t pick or choose random tutorials you find on the web. I strongly
recommend choosing for a solution that show you the complete path. The
result is almost always confusion and frustration if you pick and choose.

This approach is fine once you’ve nailed the fundamentals. As a
beginner, though, I recommend sticking with a proven solution.
If you have money to spend and you want to speed up your learning, you
can enroll in a bootcamp to immerse yourself in Swift development. The
result is that you learn a lot in a very short period.

3 Know Your Tools
An important part of your foundation is knowing the tools you work with.
And this goes beyond just Xcode. I always encourage developers,
regardless of the company you work for, to know about every aspect of
building, testing, and shipping a Cocoa application. This chapter covers
the tools you need to know about and become familiar with. Let’s start
with the workhorse of every Cocoa developer, Xcode.

Xcode
Xcode is the most popular IDE for building Cocoa applications. There are
alternatives, such as JetBrains’ AppCode, but I won’t cover those in this
book. While Xcode has served me well over the years, there is, and has
always been, room for improvement.
While it’s important that you become familiar with Xcode’s user interface,
it’s not important to spend hours or days learning the ins and outs of
Xcode. My experience has taught me that developers usually don’t have
a hard time getting up to speed with Xcode. The basics are the same for
most IDEs and you learn about the more intricate features of Xcode over
time.
But that doesn’t mean you shouldn’t dig a bit deeper from time to time.
Xcode has a slew of hidden features and keyboard shortcuts. It’s worth
spending an hour here and there reading up on Xcode, watching a
WWDC session, or simply playing around with Xcode’s user interface.
I’d like to highlight a few components of Xcode that deserve special
attention and that you need to know about.

Documentation
Documentation is a developer’s bread and butter. Xcode’s built-in
documentation browser hasn’t always been great. Fortunately, Xcode’s
documentation browser received an overhaul in Xcode 8 and 9. I used to

use Dash to explore the Cocoa SDK, but I’ve switched to the built-in
documentation browser since Xcode 8. It’s nicely structured, fast, easy to
use, and it supports tabs.
You can bring up the documentation browser from within the source
editor by pressing Option and clicking a symbol. This shows you a
summary of the symbol. You can open the documentation browser by
clicking one of the links in the pop-up window.

Xcode’s Documentation Browser

Xcode’s Documentation Browser

You can also open the documentation browser by pressing Shift +
Command + 0 or choosing Developer Documentation from Xcode’s
Window menu.

Devices
The Window menu also gives you access to the Devices and
Simulators window. This is useful if you need to download the container
of an application or add a simulator.

Organizer
Xcode’s Organizer is more powerful than many developers know or
think. It shows you a list of archives, but it also provides easy access to

crash reports. The crash reports neatly tie into Xcode’s source editor,
which is very convenient for debugging fatal issues.

Xcode’s Organizer

The organizer also allows you to export your application or send it to
iTunes Connect for testing or deployment to Apple’s App Store.

Developer Portal
Even though Xcode can communicate with Apple’s servers on your
behalf, you sometimes need to visit Apple’s developer portal to take care
of specific tasks, such as creating a certificate or configuring an App ID.
It used to be tedious to work with the Developer Portal. This has become
easier and Xcode takes care of many trivial tasks, such as adding
capabilities to an App ID and generating provisioning profiles.

Provisioning
Most developers cringe when someone drops the word provisioning. An
application needs to be provisioned for it to run on a device. This is a
necessary evil if you’re developing for Apple’s ecosystem. It’s tedious, it
drives you mad from time to time, but it’s important that you understand
why it’s necessary, how it works, and how you can resolve common
issues.
This is one of those topics that’s usually skipped or ignored, that is, until
things hit the fan. You don’t want to learn about provisioning the moment
you need to deploy a hotfix to the App Store. If you have some downtime,

spend an hour reading about and learning the ins and outs of application
provisioning. You’ll be thankful that you did when things go haywire.

Instruments
Xcode ships with several other developers tools, including Instruments.
Instruments is one of the most underused and undervalued tools in a
Cocoa developer’s toolbox. It’s powerful, versatile, and a great help for
debugging more complex issues.
While Instruments is useful, I wouldn’t focus on this tool from day one. In
fact, I wouldn’t invest much time in it in your first year unless you need it
for debugging. There are more important things to learn in the first year of
your journey. Once you’re familiar with Xcode and Cocoa development,
though, it’s certainly worth investing time in exploring Instruments.

Command Line
While it’s possible to create Cocoa applications without knowing a thing
about the command line, I’ve always found it a big asset to be familiar
with, and not afraid of, the command line. Interacting with CocoaPods or
Carthage, for example, is mostly done from the command line. Some
developers swear by the command line for many other tasks, such as
source control and running tests.
This isn’t something you need to invest time in right now, but have an
open mind about the use of the command line. If you have some time to
spare, then explore a few tutorials about the command line and how you
can use it to your advantage.

Third Party Tools
Even though Xcode works fine for Cocoa development, there are several
tools that make building Cocoa applications easier and more enjoyable. I
don’t have any affiliation with the companies that create these products.

Tower
Tower is my favorite Git client and it gets better with every release. I use
the command line for simple Git operations, but most of the time I use
Tower to get the job done. It’s a perfect fit for my workflow.

Reveal
You probably know that Xcode includes a view debugger, allowing you to
inspect the view hierarchy of a Cocoa application. Reveal is a standalone
application that performs a similar task, but it does this much, much
better. Reveal has been around for several years and it also includes
support for tvOS applications.

Charles
Charles is a cross-platform application for inspecting network traffic. It
isn’t always easy to get it up and running with a physical device, but,
once set up, it works very well and can be a lifesaver for debugging
network issues.

PaintCode
Writing drawing code is tedious and verbose. PaintCode makes this a
breeze. PaintCode is a drawing application that converts your artwork
into drawing code for several platforms. It supports a range of languages,
including Swift and Objective-C.

4 Adopt Best Practices
Whenever someone signs up for Cocoacasts, I ask them what they’d like
to achieve in the next three, six, or twelve months. Many developers tell
me they want to become a better Swift developer. This is a vague
ambition and I usually ask them what that means for them. What does it
mean to become a better Swift developer?
A common answer is that they want to learn about patterns and best
practices. That’s an interesting answer because it shows that they have
the ambition to grow as a developer and they know that their current
code can use some improvements.

What Are Best Practices
The term best practices is overused in my opinion. I prefer to use the
term good practices. What I like about software development is that
there’s rarely one solution to solve a problem. That also implies that there
are no best practices, only good practices and habits.
Apple unveiled Swift only three years ago. Unless you’re Chris Lattner,
the language is still very new to us. Many of us are still looking for good
practices to adopt. But how do you spot a good practice? Some
developers intuitively spot a good practice when they see one. It’s often a
solution to a problem that feels right. It looks elegant and, more often
than not, it’s easy to implement.
Take dependency injection as an example. This is one of the patterns I
teach in my book Learn the Four Swift Patterns I Swear By. Even though
many developers have a hard time wrapping their head around the
concept, dependency injection is easy to adopt and implement. It’s a cure
for tight coupling and an effective solution to rid a project of singletons.
Good practices aren’t necessarily the easiest or most convenient
solutions you find. Have you heard about the singleton pattern? This
pattern is easy to adopt and it’s very convenient to use in a project. But

there’s a caveat. Convenience is sometimes a code smell. I mention this
several times in the book. If something’s convenient, then you may need
to step back and take a hard look.
You shouldn’t avoid convenience, but you need to be critical about the
patterns you use and the practices you adopt. Even if you have little
experience, you need to scrutinize what you pick up. It usually only takes
a healthy dose of common sense to distinguish a pattern from an antipattern. Be critical and be honest with yourself.

Patterns
Patterns are an important aspect of software development. They’re
proven recipes to solve problems. They allow you to get work done
instead of reinventing the wheel over and over.
Later in the book, I zoom in on several patterns I strongly recommend
you take a look at. They have become an integral part of my
development workflow. It doesn’t mean that you need to use or adopt
these patterns in your projects, but it can be eye-opening to explore them
and learn from them.

Anti-patterns
There are very few patterns I recommend that you avoid altogether.
They’re often referred to as anti-patterns. There’s one pattern that I have
a strong opinion about, the singleton pattern. While I don’t consider the
singleton pattern a bad pattern or an anti-pattern, I advise to use it
sparingly. Very, very sparingly.
The primary reason the singleton pattern has a bad reputation is misuse.
A common reason developers adopt the singleton pattern is convenience.
Do you remember what I said about convenience?
You probably know that the use of globals is an anti-pattern in most
programming languages. The singleton pattern gives you global access
to the singleton object. Doesn’t this start to smell? Unfortunately, this side
effect of the singleton pattern is the primary reason many developers
adopt the pattern. Don’t do that.

Good Practices for Swift
As I mentioned earlier, with the release of Swift, many of us started
looking for and reading about good practices. They were difficult to find at
first, but, as the language evolved, it’s clear what you should and
shouldn’t do.

Embrace Optionals
For some, Swift is almost synonymous to optionals. For others, optionals
are synonymous to frustration. Optionals are an essential aspect of
Swift’s obsession with safety. And that’s a good thing. The ability to send
messages to nil in Objective-C is convenient, but it’s heavily misused.
It’s very often an easy way out for developers.
Swift puts a stop to this. The language is very clear about the meaning of
nil, the absence of a value, and it’s up to you to deal with it. Plain and
simple.
Developers new to Swift often take refuge to the exclamation mark. This
isn’t something I recommend. In fact, as I mention elsewhere in the book,
I see most uses of the exclamation as an anti-pattern. The exclamation
mark is a necessary element of the Swift language, but, as with every
invention, it’s often misused.

Learn the Language
The most common reason developers struggle with Swift is because they
don’t know the language yet. There’s nothing wrong with that since many
of us are still learning. However, whenever I find myself cursing the
compiler for yet another mysterious error message, I look for a solution.
The language is still young, but the early days of the language, when it
was barely usable, are over.
Swift 3 and 4 are a joy to use and I don’t very often find myself struggling
with the language itself. I browse the language guide or look for a
solution on the web. There’s almost certainly a solution that fits your
current need.

That’s also why I recommend investing in your education. I know that
work can get in the way from time to time, but I strongly recommend
allocating a chunk of time every day or every week dedicated to learning
something new. And I don’t mean learning a new shiny framework, such
as ARKit. Invest in your foundation. That doesn’t sound as fancy as
ARKit, but it makes your job more fun in many subtle ways.

Swift’s Core Ingredients
The more I use Swift, the more I fall in love with the language. Value
types are one of the aspects I adore about Swift. We have structs and
enums in Objective-C, but they’re not nearly as powerful or easy to use
as their counterparts in Swift. Enums are fantastic and structs are a good
fit for a wide range of problems.
Value types and reference types each have their place and we need
references types to build Cocoa applications. The next time you define a
class, though, consider creating a struct or enum. Would that also work?
Later in the book, I go into more detail about the differences and the
benefits of value types and reference types. Use value types whenever
you can and use reference types when it feels you need them. You don’t
need to choose one or the other. They complement one another quite
well.
The Swift language is composed of a small number of core values or
core ingredients. Once you discover what they are, you better understand
how the language works best and should be used. I already mentioned
value types and optionals. Later in the book, I also talk about protocols
and protocol-oriented programming.

Be Critical
Being critical is a skill every developer needs to cultivate. Learn from
others and experiment, but remain critical about the lessons you take
away and adopt. I cannot emphasize this enough.

5 Security
Security is a fundamental aspect of software development and it’s
important to know about best practices and common patterns that can
help strengthen the security of the projects you work on. I want to
emphasize that I’m not a security expert. The recommendations I provide
in this chapter are based on my experience and what I’ve learned from
fellow developers.

Make It Hard
I once read that, if someone wants to access your data, then they will
succeed. How badly they want to access your data determines whether
they’ll succeed. I don’t know whether this is true, but I tend to err on the
side of safety.
Why is this important? It changed my perspective on security. It’s naive to
think that you can outsmart people that are trained to find and extract the
information they need. That doesn’t mean you need to be complacent or
ignore the advice you read. It simply means that your actions and
motivation change slightly.
An effective approach to security is to have the mindset to make it hard
for the other party to access the data you’re trying to protect. In other
words, you add several layers of security to protect the data of the user.
Let’s start with the basics.

Plain Text
If you have some experience developing software, you most likely know
that you shouldn’t store sensitive information in plain text. Ever. Don’t
store the user’s username and password in the user defaults database,
for example. Use the keychain to protect this type of sensitive
information.

The same applies to networking. Apple and Google are actively forcing
developers to move away from HTTP and use SSL by default. Apple’s
App Transport Security encourages developers to be aware of the
security risks of their applications. Make sure that your application
communicates with remote services over a secure connection. This isn’t
always possible if you aren’t in control of the remote service. In such a
scenario, it’s up to you to decide what the next best option is.
But SSL may not always be sufficient. Your application is still susceptible
to, for example, man-in-the-middle attacks. You can remedy this by
adopting certificate pinning, adding an extra layer of security.

Obfuscating Information
A common question I receive is how to best hide or obfuscate sensitive
information that’s bundled with your application. That’s a good question.
The answer may disappoint you, though. As I mentioned earlier in this
chapter, there’s always a way for people with bad intentions to get a hold
of the information they need. You need to consider the sensitivity of the
information you’re trying to protect.
The same advice applies, though. Make it as hard as possible. But, at the
same time, consider the sensitivity of the information you’re protecting.
Don’t store sensitive information, such as API keys, in your application’s
Info.plist. It’s easy to dissect an application you downloaded from the
App Store and inspect the contents of the Info.plist.
I usually store sensitive information as private constants in a
configuration file, which means it’s compiled alongside the application.
This doesn’t make it impossible to extract the sensitive information, but it
makes it less trivial.

Fetching Sensitive Information
You can go one step further and avoid storing keys or credentials in the
application itself. Instead, your application contacts a remote service and
asks for credentials every time it needs to communicate with that service.
This requires a dedicated infrastructure and a lot more work up front, but
it adds a powerful layer of security.

Encryption
Encryption is an effective solution to protect the user’s data. Realm, for
example, has built-in support for encrypting the data stored in its
database. For Core Data, however, this is less trivial. I hope Apple will
make this less cumbersome in a future release of the framework.
The data the user stores on their device is automatically encrypted if the
device is protected with a password or Touch ID. Only you, the user, can
unlock the data stored on your device because you hold the key to
decrypt it, not Apple. It’s great to see that Apple continues to invest in the
privacy and security of its customers. Apple’s motivation is a bit more
nuanced, though.

Privacy
A lot has been written about privacy and protecting the user’s privacy.
Unfortunately, many developers don’t realize that this also means
protecting the user’s privacy from companies that offer services they use
day in day out. If your application uses analytics or displays ads, then
you’re exposing the user’s personal information to the companies behind
these services.
I used to use Fabric for crash reporting and analytics, but I no longer do
for personal projects. As a developer, it’s my responsibility to protect the
user’s privacy and they expect that from me. I understand that many
developers don’t have this luxury, but I still believe that you should, at a
minimum, consider the option and be aware of the information you may
be exposing to third parties.
If you include a third party SDK in your application and you don’t have
access to the source, then how do you know what information you’re
sharing with this third party? You don’t. That’s important to keep in mind.

Logging and Debugging
Logging information to the console is my favorite technique to debug
issues because it’s simple and to the point. It’s a technique many of us
use, but it’s also a potential security problem. Many developers forget
that print or log statements also log information to the console in

production. This can be useful and intentional, but it can also be a
security issue.
I hope you’re not logging credentials or other sensitive information. Even
fragments of the user’s data shouldn’t be logged in production. If you
need to generate logs, then I recommend looking into remote logging in
combination with data encryption. Avoid that a third party, any third party,
can access the logs you generate.

Educating Your Client
The role of a developer is often reduced to writing code and solving a
problem. Not only is this incorrect, I strongly believe any developer,
regardless of their experience, should also provide a technical service to
the parties they work with. What does that mean? If you’re told to
implement a solution, then it’s your responsibility to inform your client or
project manager about any security risks or problems.
I believe it’s the task of the developer to educate the client. The client still
decides what happens and what needs to be implemented, but they
should at a minimum be aware of the risks involved. I’ve implemented
several solutions I didn’t agree with, but I tried to educate the client about
alternative solutions that were safer.
At one point I inherited a project in which the user’s credentials were
stored in the user defaults database. Even though there was no room to
refactor this glaring security hole, I informed the client about the problem.
For a developer, it can be frustrating not having final say in such
arguments, but that’s how it is. This is very different if you build a product
business in which you make the calls.

6 Don’t Ignore Your Foundation
It’s common for companies to build an in-house framework that lies on
top of Apple’s frameworks. Some frameworks fix bugs and add
conveniences to Apple’s APIs while others abstract away large portions
of the native frameworks.
It’s clear why this is a common practice in large companies, especially
agencies. You don’t want to reinvent the wheel every time you need, well,
a wheel. But there are inherent risk involved that are often ignored or not
spoken about.

Under the Hood
One of the most important pieces of advice in this book is simple but so
important, invest in your foundation. Once you have a solid foundation,
you’ll notice that picking up a new framework or solving a challenging
problem is possible. It’s no longer complex, it’s simply challenging.
But if you land a job at a company that kindly forces you to use the inhouse framework then your foundation is compromised. I’m sure you can
build beautiful applications that work very well. But I wonder if you know
and understand what’s happening under the hood? What happens if you
move to a new company? An in-house framework is almost always the
company’s intellectual property. Do you know how to build applications
without it?

Dependencies
This brings us to dependencies, a topic I cover in more detail later in the
book. I always try to minimize the number of dependencies I include in a
project. Every dependency needs to earn its way onto the project. The
reality is that most don’t make it into the project’s Podfile or Cartfile,
which is a good thing.

I’m a big fan of lightweight abstractions or wrappers around frameworks.
Core Data is a fine example. I don’t use a library to work with Core Data,
but I create a handful of files that include convenience methods to
interact with the framework. These are usually specific to the project.

Don’t Ignore the Fundamentals
Investing in the fundamentals is the best investment you can make as a
developer, regardless of your experience. Even if the company you work
for uses an in-house framework, I encourage you to continue investing in
the fundamentals of the platform you build software for.

7 Respect the SDK
When you’re new to a language or framework, it occasionally happens
that you find yourself fighting the language or framework. Whenever you
feel that you’re coding yourself in a corner, you should stop and take a
step back.
Take the Cocoa SDK as an example. The engineers at Apple aren’t
stupid and they carefully craft the APIs of the various libraries and
frameworks. If you find yourself jumping through a lot of hoops to
accomplish a simple task, then it’s very likely that there’s a better solution
you’re not aware of.

Know Your Limitations
At the same time, you should be aware of the limitations of the API you’re
using. This is difficult when you’re starting out. Take the user defaults
system as an example. The user defaults database is meant for storing
small chunks of data. These are stored as key-value pairs.
While you can store complex object graphs in the user defaults database
(as long as you stick to the supported types) don’t be naive and store
megabytes of data in the user defaults database. It’ll probably work, but it
won’t be a performant or scalable solution.

Respect the SDK
A very common type of question on Stack Overflow is “How do I
customize …?” Fill in the blank. Most of the components of the UIKit
framework are very customizable, but there are times when you run into
limitations. Apple does its best to keep the user interface of applications
on its platforms consistent and by limiting the customization of user
interface components it tries to discourage too much customization.
A few weeks ago, I was looking for a solution to a trivial problem. I
wanted to modify the color of the clear button of a text field, an instance

of the UITextField class. Several Stack Overflow entries suggested to
look for the clear button in the view hierarchy and setting its tint color
property to the desired color. This is a bad idea and a common example
of running into the limitation of an API.
The UITextField class currently doesn’t support modifying the tint color of
the clear button. That’s a fact. The only option I had was filing a bug and
move on. I ended up implementing a custom solution that solved the
problem.
I’m still not sure if the inability to customize the tint color of the clear
button is a deliberate choice made by Apple, but the truth is that the API
of the UITextField class doesn’t support it. That means that I’m not able
to use the default implementation of UITextField if I need to customize
the clear button. You decide if you want to push the limits, but you do so
at your own risk.
Digging into the view hierarchy of the text field may resolve the issue
today, and it did for many developers judged by the number of upvotes,
but you’re building a house on quicksand. The moment Apple makes
changes to the internals of the UITextField class, your solution stops
working. If you’re lucky, the user will see the default clear button. If you’re
not so lucky, your application crashes or is rejected by Apple.

9 Design Patterns
In this chapter, I discuss some of the design patterns I use day in day out.
They’re my bread and butter. If you’re a Cocoacasts reader or student,
then you may already be familiar with some of them.

Model-View-Controller
I bet you’re already familiar with Model-View-Controller, or MVC for
short. The Model-View-Controller pattern is a widely used design pattern
for architecting software applications. It’s been around for several
decades and made its way to many languages, frameworks, and
libraries.
Cocoa applications are centered around the Model-View-Controller
pattern, and many of Apple’s frameworks make heavy use of MVC. It’s
therefore important that you know what it is, why it’s a popular choice to
architect software applications, and, let’s be honest, where it falls short.

What Is MVC
As the name suggests, the Model-View-Controller pattern breaks an
application up into three components or layers, Model, View, and
Controller.
Model

The model layer is responsible for the business logic of the application. It
manages the application state, which also includes reading and writing
data, persisting application state, and it may even include tasks related to
data management, such as networking and data validation.

The M In MVC
View

The view layer has two important tasks, presenting data to the user and
handling user interaction. A core principle of the MVC pattern is the view
layer’s ignorance with respect to the model layer. Views are dumb
objects. They only know how to present data to the user and they don’t
know or understand what they’re presenting. This makes them flexible
and easy to reuse.

The V In MVC
Controller

The view layer and the model layer are glued together by one or more
controllers. In an iOS application, that glue is a view controller, an
instance of the UIViewController class or a subclass thereof. In a macOS
application, that glue is a window controller, an instance of the
NSWindowController class or a subclass thereof.

The C In MVC

A controller knows about the view layer as well as the model layer. This
often results in tight coupling, making controllers the least reusable
components of an application based on the Model-View-Controller
pattern. The view and model layers don’t know about the controller. The
controller owns the views and the models it interacts with.

Model-View-Controller in a Nutshell

Advantages
The Model-View-Controller pattern has earned its stripes over several
decades and there are several reasons why it’s such a popular design
pattern.
Separation of Concerns

The most obvious advantage of the Model-View-Controller pattern is a
clear separation of concerns. Each layer of the Model-View-Controller
pattern is responsible for a clearly defined aspect of the application. In

most applications, there’s no confusion about what belongs in the view
layer and what belongs in the model layer.
What goes into controllers is often less clear. The result is that controllers
are frequently used for everything that doesn’t clearly belong to the view
layer or the model layer.
Reusability

While controllers are often not reusable, view and model objects are
mostly easy to reuse. If the Model-View-Controller pattern is correctly
implemented, the view layer and the model layer should be composed of
reusable components.

Problems
If you’ve spent any amount of time reading books or tutorials about iOS
or macOS development, then you’ve probably come across people
complaining about the Model-View-Controller pattern. Why is that?
What’s wrong with the Model-View-Controller pattern?
A clear separation of concerns is great. It makes your life as a developer
easier. Projects are easier to architect and structure. That’s only part of
the story, though. Much of the code you write doesn’t belong to the view
layer or the model layer. No problem. Dump it in the controller. Problem
solved? Not really.

An Example
Data formatting is a common task. Imagine that you’re developing an
invoicing application. Each invoice has a creation date. Depending on the
locale of the user, the date of an invoice needs to be formatted differently.

An Example

The creation date of an invoice is stored in the model layer and the view
displays the formatted date. That’s obvious. But who’s responsible for
formatting the date? The model? Maybe. The view? Remember that the
view shouldn’t need to understand what it’s presenting to the user. But
why should the model be responsible for a task related to the user
interface?
Wait a minute. What about our good old controller? Sure. Dump it in the
controller. After thousands of lines of code, you end up with a bunch of
overweight controllers, ready to burst and impossible to test. Isn’t MVC
the best thing ever?

How Can We Solve This?
In recent years, another pattern has been gaining traction in the Cocoa
community. It’s commonly referred to as the Model-View-ViewModel
pattern, MVVM for short. The origins of the MVVM pattern lead back to
Microsoft’s .NET framework and it continues to be used in modern
Windows development. In the next section of this chapter, we take a
closer look at the Model-View-ViewModel pattern and the advantages it
has over the Model-View-Controller pattern.

Model-View-ViewModel
How does the Model-View-ViewModel pattern solve the problems we
described earlier? The Model-View-ViewModel pattern introduces a
fourth component, the view model. The view model is responsible for

managing the model and funneling the model’s data to the view via the
controller. This is what that looks like.

Model-View-ViewModel in a Nutshell

Despite its name, the MVVM pattern includes four components or layers,
the Model, the View, the View Model, and the controller.
The implementation of a view model can sometimes be straightforward,
translating data from the model to values the view layer can display. The
controller is no longer responsible for this ungrateful task. Because view
models have a close relationship with the models they consume, they’re
often considered more model than view.
Let’s take a look at the advantages MVVM has over MVC. Why would
you even consider trading the Model-View-Controller pattern for the
Model-View-ViewModel pattern?

Advantages of MVVM
We already know that the Model-View-Controller pattern has a few flaws.
With that in mind, what are the advantages MVVM has over MVC?
Better Separation of Concerns

Let me start by asking you a simple question. What do you do with code
that doesn’t fit or belong in the view or model layer? Do you put it in the
controller layer? Don’t feel guilty, though. This is what most developers
do. The problem is that it inevitably leads to massive controllers that are
difficult to test and manage.

The Model-View-ViewModel pattern presents a better separation of
concerns by adding view models to the mix. The view model translates
the data of the model layer into something the view layer can use. The
controller layer is no longer responsible for this task.
Improved Testability

View (iOS) and window (macOS) controllers are notoriously hard to test
because of their close relation to the view layer. By migrating some
responsibilities, such as data manipulation, to the view model, testing
becomes much easier. Testing view models is surprisingly easy. Testing?
Easy? Absolutely.
Because a view model doesn’t have a reference to the view controller
that owns it, it’s easy to write unit tests for a view model. Another benefit
of MVVM is improved testability of view and window controllers. The
controller no longer depends on the model layer, which makes them
easier to test.
Transparent Communication

The responsibilities of the controller are reduced to controlling the
interaction between the view and model layer. The view model provides a
transparent interface to the view controller, which it uses to populate the
view layer and interact with the model layer. This results in a transparent
communication between the four components or layers of your
application.

Basic Rules
There are six key elements that define the Model-View-ViewModel
pattern. I sometimes refer to these as rules. However, once you
understand how the Model-View-ViewModel pattern does its magic, it’s
fine to bend or break some of these rules.
Rule #1

First, the view doesn’t know about the view controller it’s owned by.
Remember that views are supposed to be dumb. They only know how to
present what they’re given by the view controller to the user. This is a rule
you shouldn’t break. Ever.

The view doesn’t know about the view controller it’s
owned by.
Rule #2

Second, the view or window controller doesn’t know about the model.
This is something that separates MVC from MVVM.

The view controller doesn’t know about the model.
Rule #3

The model doesn’t know about the view model it’s owned by. This is
another rule that you shouldn’t break. The model should have no clue
who it’s owned by.

The model doesn’t know about the view model it’s
owned by.
Rule #4

The view model owns the model. In a Model-View-Controller application,
the model is usually owned by the view or window controller.

The view model owns the model.
Rule #5

The view or window controller owns the view or window. This relationship
remains unchanged.

The view controller owns the view.
Rule #6

And finally, the controller owns the view model. It interacts with the model
layer through one or more view models.

The controller owns the view model.

Give It a Try
If you’re new to Cocoa and Swift development, then I recommend
sticking with the Model-View-Controller pattern. It’s a proven pattern that
many of us have used for years to build software. But if you notice that
you’re starting to hit the limits of the Model-View-Controller pattern, then
it may be time to look for an alternative.
The Model-View-ViewModel pattern has changed how I write and think
about software. Even though the changes it introduces are modest, the
results are substantial. Combine the Model-View-ViewModel pattern with

reactive programming, which I discuss later in this chapter, and you have
a potent recipe to build software.

Singletons
The singleton pattern is a pattern developers quickly become familiar
with. When I first started dabbling with Cocoa development, I almost
immediately came into contact with the singleton pattern. Many Cocoa
frameworks, including UIKit and Foundation, use the singleton pattern.
Because the Cocoa SDK makes use of the singleton pattern, developers
think that it’s fine to use singletons. It is fine to use singletons, but it’s
more nuanced than this.

What Is the Singleton Pattern
The concept is very simple. The singleton pattern ensures only one
instance of a class is instantiated for the lifetime of the routine or
application. The Cocoa frameworks often refer to a shared object or a
shared instance. Take a look at these examples. URLSession and
UserDefaults are both defined in the Foundation framework.
1
2
3
4
5

// Shared Session Object
let session = URLSession.shared
// Shared Defaults Object
let userDefaults = UserDefaults.standard

With the above definition in mind, the singleton pattern appears to be a
useful design pattern. Unfortunately, many developers misuse the
singleton pattern and use it to conveniently access an object from
anywhere in a project. Having global access to a singleton is nothing but
a side effect of the singleton pattern. It’s not what the singleton pattern is
about.

Singletons Everywhere
Whenever I talk about singletons, I like to bring up Maslow’s hammer
analogy.
I suppose it is tempting, if the only tool you have is a hammer, to
treat everything as if it were a nail. — Abraham Maslow

A surprising number of developers struggle with this problem. The
singleton pattern appears to be solving a common problem, accessing an
object in various places of a project. A singleton, nothing more than a
fancy global, looks like the perfect fit for the problem. And it is the perfect
fit if all you want to do is solve that problem. There’s more to the story,
though.
Have you ever wondered why some experienced developers consider the
singleton pattern an anti-pattern? Why is it that such a useful pattern is
often avoided by more senior developers?

Sacrificing Transparency for Convenience
By using singletons, you almost always sacrifice transparency for
convenience. This is a problem I bring up frequently in this book. The
question is, “How much are you willing to sacrifice for that little bit of
convenience?” Convenience shouldn’t rank high on your priority list if
you’re working on a software project. Let me show you with an example
what the problem is.
By using singletons, you almost always sacrifice transparency for
convenience.
A common problem in software projects is user management. This
means that a user model object needs to be created and managed.
There are many solutions to this problem. If you’re a fan of the singleton
pattern, then you might create a singleton user object or a manager class
that manages the currently signed in user. Only a single user can be
signed in at a time. Right?
Problem solved? It’s true that you can now access the currently signed in
user from anywhere in your project. While this may seem like the best
thing since sliced bread, it introduces several problems.
Consider the following question. Which object is allowed to modify the
user model object? Easy. The manager object managing the user. Hmm
… but isn’t the manager object accessible from anywhere in your project?
This means that the user model object can be modified from anywhere in
your project. If you’re still with me, then I hope you can see that this is

starting to sound less and less like the great idea it initially appeared to
be.
How are you going to make sure that the objects that depend on the
currently signed in user are notified when the user is modified? Easy.
Notifications. Another popular option is to use a pattern similar to Java’s
observer pattern. You could use key-value observing, but do you really
want to observe the properties of an object that’s managed by a
singleton? That sounds like asking for trouble.

Losing Track of Everything
I agree that the singleton pattern seems convenient and it may
occasionally be warranted to use it, but the drawbacks almost always
outweigh the benefits. Unfortunately, the drawbacks are very subtle at
first and that’s what misleads many developers.
Unfortunately, the drawbacks are very subtle at first and that’s what
misleads many developers.
The most important drawback of the singleton pattern is sacrificing
transparency for convenience. Consider the earlier example. Over time,
you lose track of the objects that access the user model object and, more
importantly, the objects that modify its properties.
The initial advantage of using a singleton, convenience, becomes the
most important problem. Ironic. Isn’t it. By using singletons in your
project, you start to create technical debt. Singletons tend to spread like a
virus because it’s so easy to access them. It’s difficult to keep track of
where they’re used and getting rid of a singleton can be a refactoring
nightmare in large or complex projects.
Once the singleton pattern becomes an accepted practice in a project, it’s
difficult to move the project forward without using even more singletons.
The structure of the project may seem flexible and loosely coupled, but
it’s anything but that.

Substituting Singletons With Dependency Injection

As I mentioned earlier, singletons have the tendency to spread like a
virus. The cure to solve singleton disease is dependency injection. I
cover dependency injection in more detail a bit later in this chapter.
While a key advantage of the singleton pattern is convenience, the most
important advantage of dependency injection is transparency. I like
transparency.
If an object requires a valid user model object to do its job, then that user
model object should be injected as a dependency. It’s easy to translate
this requirement into code. Take a look at the following example.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

class User {
var firstName = ""
var lastName = ""
}
class NetworkController {
let user: User
init(user: User) {
self.user = user
}
}

This snippet shows any developer working with the NetworkController
class that it depends on a valid User instance. This is also known as
passing an object by reference. It’s less convenient than using a
singleton, but it pays dividends in the long run. It adds clarity to the
codebase, unambiguously showing which objects depend on which
objects.
It’s an advantage that passing an object by reference is less convenient.
Huh? It forces you to consider your decision. Does the NetworkController
class need access to the user model object? Would it suffice to pass the
user’s username and password instead? Dependency injection can be a
useful tool to define the requirements of an object.
Dependency injection can be a useful tool to define the requirements
of an object.

Moving Away From Singletons

A few years ago, I started working on a client project that was littered with
singletons. Some singletons even referenced other singletons, adding to
the problem. After several rounds of refactoring, I managed to eliminate
most of the singletons from the project, which drastically increased
transparency and robustness.
Have you ever worked on a project nobody in your team wanted to
touch? Modifying a handful of lines in one class could cause mayhem in
a distant, unrelated component of the project? This is not uncommon for
projects that make heavy use of singletons.
Another benefit of ridding a project of singletons relates to testing. Writing
unit tests without having to worry about singletons is fantastic. It really is.
Combine this with dependency injection and you have a great
combination to work with.

Are Singletons Bad
My stance on singletons varies from day to day. If I had a rough day
battling singletonitis, I dislike them with a passion. The truth is that
singletons aren’t inherently bad if they’re used correctly. The goal of the
singleton pattern is to ensure only one instance of a class is alive at any
one time. That, however, is not the goal many developers have in mind
when using singletons.
Singletons are very much like the good things in life; they’re not bad if
used in moderation. The next time you’re about to create a singleton,
consider your motivation for creating it. Is it convenience? Then you
should not create that singleton. Period. That’s the simple rule I apply.

Dependency Injection
My favorite quote about dependency injection is a quote by James Shore.
It summarizes much of the confusion that surrounds dependency
injection.
“Dependency Injection” is a 25-dollar term for a 5-cent concept. —
James Shore

When I first heard about dependency injection, I figured it was a
technique too advanced for my needs at that time. I could do without
dependency injection, whatever it was.

What Is It
I later learned that, if boiled down to its bare essentials, dependency
injection is a simple concept. James Shore offers a succinct and
straightforward definition of dependency injection.
Dependency injection means giving an object its instance variables.
Really. That’s it. — James Shore
For developers new to dependency injection, it’s important to learn the
basics before relying on a framework or library. Start simple. Chances are
that you already use dependency injection without realizing it.
Dependency injection is nothing more than injecting dependencies into
an object instead of tasking the object with the responsibility of creating
its dependencies. Or, as James Shore puts it, you give an object its
instance variables instead of creating them in the object.

An Example
In the example below, we define a UIViewController subclass that
declares a property, requestManager, of type RequestManager?.
1 import UIKit
2
3 class ViewController: UIViewController {
4
5
var requestManager: RequestManager?
6
7 }

We can set the value of the requestManager property one of two ways.
Without Dependency Injection

The first option is to task the ViewController class with the instantiation of
the RequestManager instance. We can make the property lazy or initialize
the request manager in the view controller’s initializer. That’s not the

point, though. The point is that the view controller is in charge of creating
the RequestManager instance.
1 import UIKit
2
3 class ViewController: UIViewController {
4
5
var requestManager: RequestManager? = RequestManager()
6
7 }

This means that the ViewController class not only knows about the
behavior of the RequestManager class. It also knows about its instantiation.
That’s a subtle but important detail.
With Dependency Injection

In the second option, we inject the RequestManager instance into the
ViewController instance. Even though the result may appear identical, it
isn’t. By injecting the request manager, the view controller doesn’t know
how to instantiate the request manager.
1
2
3
4
5

// Initialize View Controller
let viewController = ViewController()
// Configure View Controller
viewController.requestManager = RequestManager()

Many developers immediately discard the second option because it is
cumbersome and unnecessarily complex. But if you consider the
benefits, dependency injection becomes more appealing.

Another Example
Let me show you another example to emphasize the point I made in the
previous section. Take a look at the following example.
1 protocol Serializer {
2
3
func serialize(data: AnyObject) -> NSData?
4
5 }
1 class RequestSerializer: Serializer {
2
3
func serialize(data: AnyObject) -> NSData? {
4
...
5
}
6
7 }

1 class DataManager {
2
3
var serializer: Serializer? = RequestSerializer()
4
5 }

The DataManager class has a property, serializer, of type Serializer?. In
this example, Serializer is a protocol. The DataManager class is in charge
of instantiating an instance of a type that conforms to the Serializer
protocol, the RequestSerializer class in this example.
Should the DataManager class know how to instantiate an object of type
Serializer? Take a look at the following example to show the power of
protocols and dependency injection.
1
2
3
4
5

// Initialize Data Manager
let dataManager = DataManager()
// Configure Data Manager
dataManager.serializer = RequestSerializer()

The DataManager class is no longer in charge of instantiating the
RequestSerializer class. It no longer assigns a value to its serializer
property. In fact, we can replace RequestSerializer with another type as
long as it conforms to the Serializer protocol. The DataMananger no
longer knows or cares about these details.

What You Gain
I hope the above examples have at least captured your attention. Let me
list a few additional benefits of dependency injection.
Transparency

By injecting the dependencies of an object, the responsibilities and
requirements of a class or structure become more clear and more
transparent. By injecting a request manager into a view controller, we
understand that the view controller depends on the request manager and
we can assume the view controller is responsible for request managing
and/or handling.
Testing

Unit testing is so much easier with dependency injection. Dependency
injection allows developers to substitute an object’s dependencies with

mock objects, making unit tests easier to set up and isolate behavior.
1 class MockSerializer: Serializer {
2
3
func serialize(data: AnyObject) -> NSData? {
4
...
5
}
6
7 }
1
2
3
4
5

// Initialize Data Manager
let dataManager = DataManager()
// Configure Data Manager
dataManager.serializer = MockSerializer()

Separation of Concerns

As I mentioned and illustrated earlier, another subtle benefit of
dependency injection is a stricter separation of concerns. The
DataManager class in the above example isn’t responsible for instantiating
the RequestSerializer instance. It doesn’t need to know how to do this.
Even though the DataManager class is concerned with the behavior of its
serializer, it isn’t, and shouldn’t be, concerned with its instantiation. What
if the RequestManager of the first example also has a number of
dependencies. Should the ViewController be aware of those
dependencies too?
Coupling

The example with the DataManager class illustrated how the use of
protocols and dependency injection can reduce coupling in a project.
Protocols are incredibly useful and versatile in Swift. This is one scenario
in which protocols really shine. Later in this chapter, I write more about
protocols and protocol-oriented programming.

Types
Most developers consider three forms or types of dependency injection:
dependency injection through an initializer
dependency injection using properties
dependency injection in methods

These types shouldn’t be considered equal, though. Let me list the pros
and cons of each type.
Initializer

I personally prefer to pass dependencies during the initialization of an
object because this has several key benefits. The most important benefit
is that dependencies passed in during initialization can be made
immutable. This is very easy to do in Swift by declaring the properties for
the dependencies as constants. Take a look at the below example.
1 class DataManager {
2
3
private let serializer: Serializer!
4
5
init(serializer: Serializer) {
6
self.serializer = serializer
7
}
8
9 }
1
2
3
4
5

// Initialize Request Serializer
let serializer = RequestSerializer()
// Initialize Data Manager
let dataManager = DataManager(serializer: serializer)

The only way to set the serializer property is by passing it as an
argument during initialization. The init(serializer:) method is the
designated initializer and guarantees that the DataManager instance is
correctly configured. Another benefit is that the serializer property
cannot be mutated.
Because we’re required to pass the serializer as an argument during
initialization, the designated initializer clearly shows what the
dependencies of the DataManager class are.
Internal or Public Properties

Dependencies can also be injected by declaring an internal or public
property on the class or structure that requires the dependency. This may
seem convenient, but it adds a loophole in that the dependency can be
modified or replaced. In other words, the dependency isn’t immutable.
1 import UIKit
2
3 class ViewController: UIViewController {
4

5
6
7 }
1
2
3
4
5

var requestManager: RequestManager?

// Initialize View Controller
let viewController = ViewController()
// Configure View Controller
viewController.requestManager = RequestManager()

Methods

Dependencies can also be injected whenever they’re needed. This is
easy to do by declaring a method that accepts the dependency as a
parameter. In the example below, the serializer isn’t a property on the
DataManager class. Instead, the serializer is injected as an argument of
the serializeRequest(_:withSerializer:) method.
1 class DataManager {
2
3
func serializeRequest(request: Request, withSerializer serialize\
4 r: Serializer) -> NSData? {
5
...
6
}
7
8 }

Even though the DataManager class loses some control over the
dependency, the serializer, this type of dependency injection introduces
flexibility. Depending on the use case, we can choose what type of
serializer to pass into serializeRequest(_:withSerializer:).

Singletons
Earlier in this chapter, I showed you how dependency injection can be
used to eliminate the need for singletons in a project. I’m not a fan of the
singleton pattern and I avoid it whenever possible. Even though I don’t
consider the singleton pattern an anti-pattern, I believe they should be
used very, very sparingly. The singleton pattern increases coupling
whereas dependency injection reduces coupling.
Too often, developers use the singleton pattern because it’s an easy
solution to a, often trivial, problem. Dependency injection, however, adds
clarity to a project. By injecting dependencies during the initialization of
an object, it becomes clear what dependencies the target class or
structure has and it also reveals some of the object’s responsibilities.

Dependency injection is one of my favorite patterns because it helps me
stay on top of complex projects. This pattern has so many benefits. The
only drawback I can think of is the need for a few more lines of code, but
that’s a drawback I’m happy to accept.

References, Delegation, and Notifications
A typical Cocoa application is composed of dozens and dozens of
objects, working together to make your application tick. To get the job
done, these objects need the ability to talk to each other. In this section,
we take a look at three common patterns that enable objects to
communicate with one another. We also discuss when to use which
pattern and, more importantly, when to avoid a particular pattern.

References
On iOS, a view is typically owned and managed by a view controller. This
is textbook Model-View-Controller. The view controller keeps a reference
to the view it manages and talks to it directly.
Even though there’s nothing wrong with this approach, it’s important to
understand that it introduces tight coupling. The implementation of the
view controller is tightly coupled to that of the view. The opposite isn’t
true, though. The view is unaware of the view controller and, as a result,
its implementation isn’t coupled and doesn’t depend on that of the view
controller.
Keeping a reference to an object is the most direct way of
communication. Because it introduces coupling between objects, it
cannot, or should not, be used in every context.

Delegation
At first glance, delegation appears to be similar to the first approach. The
key difference is that the objects are loosely coupled. The
UITableViewDelegate protocol is a good example of delegation.
Like any other view, a table view is in charge of responding to user
interaction. Even though a table view can detect user interaction, it

doesn’t know how to interpret the touch events. This seeming
disadvantage is what makes table views reusable components.
A table view informs its delegate about the touch events it detects. It’s the
responsibility of the table view’s delegate, a view controller, for example,
to handle table view interactions. A table view is loosely coupled to its
delegate through the UITableViewDelegate protocol. The delegate object
is also loosely coupled to the table view. All it needs to do is conform to
the UITableViewDelegate protocol by implementing the methods defined
by the protocol.
Any class instance conforming to the UITableViewDelegate protocol can
act as the table view’s delegate. The table view doesn’t care and doesn’t
need to know which object acts as the table view’s delegate as long as it
conforms to the UITableViewDelegate protocol.
This is an example of protocol-oriented programming, which we cover
later in this chapter. As the name implies, the table view delegates tasks
to the delegate object. Delegation is a very common design pattern in
Cocoa applications and frameworks.

Notifications
Ideally, delegation is used to enable unidirectional communication
between two objects. What if an object has a message that’s of interest
to two, three, or dozens of objects? For Cocoa applications, the
recommended approach is posting a notification through a notification
center.
The NotificationCenter class, defined in the Foundation framework,
provides an interface for broadcasting messages within a Cocoa
application. To make this possible, two elements need to be in place:
an object posting the notification
one or more objects interested in the notification
An object needs to tell a notification center that it’s interested in receiving
notifications with a particular name. It can optionally specify which objects
they’d like to receive notifications from. What does that look like in code?

1
2
3
4

let defaultCenter = NotificationCenter.default
defaultCenter.addObserver(self, selector: #selector(synchronizationD\
idFinish(_:)), name: Notification.Name.SynchronizationDidFinish, obj\
ect: nil)

The object that broadcasts the notification uses the same notification
center to post a notification with a particular name. It can optionally
include additional information in the form of a dictionary.
1 let defaultCenter = NotificationCenter.default
2 defaultCenter.post(name: Notification.Name.SynchronizationDidFinish,\
3 object: self, userInfo: [ "success" : true ])

If an object is no longer interested in receiving notifications with a
particular name, it simply removes itself as an observer.
1 NotificationCenter.default.removeObserver(self)

Be Careful
Notifications are an essential aspect of Cocoa development. Apple’s
frameworks define dozens and dozens of notifications for various
purposes. This may give you the impression that notifications are a
proven, reliable, and robust solution to send messages from one object to
another. While that’s true, there’s a catch.
Coupling

We like loose coupling. Right? Tight coupling is bad. This is true, but how
loosely coupled is the notification pattern. If you have an object that
subscribes to the UIApplicationDidEnterBackground notification, you
implicitly tie its implementation to the UIKit framework. There’s nothing
wrong with this, but it’s important to consider this. You’re implicitly adding
a dependency to the UIKit framework.
Debugging

In my early days developing Cocoa applications, I made ample use of
two patterns, singletons and notifications. Looking back it seems only
natural. I was trying to solve common problems and I found two solutions
that were easy to implement.
Notifications aren’t bad and they’re very useful at times, but it’s important
to understand that you pay for them in transparency.

The first project I started and successfully finished made heavy use of
notifications. Debugging this project was a nightmare at times. Xcode’s
debugger can make it easy to debug common problems, but notifications
can make debugging much more complex and tedious.
A notification sent by one object can trigger a response in a distant object
in your project. The only link between these objects is the notification.

If You Decide to Use Notifications
If you decide that notifications are the right solution to a problem, then, by
all means, use them. However, I encourage you to adopt a handful of
good practices if you do. Don’t use string literals to name your
notifications. Ever. Do yourself a favor and create an extension for
Notification and follow Apple’s lead. You can use your own naming
scheme, but I advise you to use constants for notification names.
1
2
3
4
5
6
7
8

import Foundation
extension Notification.Name {
static let DidResetStatistics = Notification.Name(rawValue: "Did\
ResetStatistics")
}

Use notifications sparingly and only if there’s no other alternative that’s
straightforward to implement. For example, don’t use notifications instead
of delegation. If you only intend to notify one object, then delegation is
usually the right choice, not notifications.
Ask yourself whether notifications are the right solution to solve the
problem. Be honest with yourself. Do you use notifications because it’s
convenient or because it’s the right solution to the problem you’re
solving?
That’s what I truly enjoy about software development. There are recipes
and there are tools, but it’s up to you, the developer, to use the right
combination. There are usually multiple solutions, but no two solutions
are the same. One solution is often preferred over another.

What About Key-Value Observing?

Key-Value Observing, or KVO for short, is a solution that enables objects
to observe properties of other objects. Key-Value Observing and KeyValue Coding are important aspects of Cocoa programming. They’re
heavily used by bindings on macOS, for example. That said, it’s
important to understand that KVO is a passive form of communication
between objects.

When To Use What
References

Object references make sense if both objects have a clear or logical
relationship with one another. A view controller, for example, keeps a
reference to the view it manages. It’s important to understand that the
owner takes responsibility for the lifetime of the object it owns. This isn’t
true for delegation.
Delegation

Developers new to Cocoa are often confused by delegation and
notifications. There’s no need to be confused, though. Delegation should
only be used if one object needs to talk to another object. It’s a one-toone relationship and the communication is often unidirectional, from the
delegating object to its delegate.
Delegation works best with protocols. A delegate object, the object being
talked to, can be any object as long as it conforms to the delegate
protocol. Remember how a table view talks to its delegate. It doesn’t
know which object it delegates tasks to. It only knows that it conforms to
the UITableViewDelegate protocol. As a result, delegation promotes a
loosely coupled object graph.
Notifications

Notifications are used if an object wants to notify other objects of an
event. The sender of the notification doesn’t care which objects subscribe
to the notification or how they handle the broadcast. Even though this
may seem the best solution since objects are seemingly uncoupled, it
introduces a subtle form of coupling as I mentioned earlier in this chapter.
One Solution to Rule Them All

Great. I’m going to stick with notifications. For everything. It offers the
most flexibility, well, not exactly. It’s true that notifications are great for
communication between objects that are unaware of each other.
As I wrote earlier, an application that relies heavily on notifications quickly
becomes a nightmare to maintain and debug. Remember to only use
notifications if you have no other option. Notifications aren’t bad, but they
shouldn’t be overused either. They’re no cure-all.

Closures as an Alternative to Delegation
Even though I like using delegation in Cocoa applications, it can
sometimes become a bit overwhelming. Large applications can end up
with dozens of delegate protocols, with some of them defining only a
single method.
An alternative approach is to use closures (or blocks in Objective-C). I
only recommend this alternative as a substitute for compact delegate
protocols. Let’s look at an example to better understand how this works.
Imagine an application that manages a list of items. The user can add
items to the list by tapping a button in the navigation bar. Each item is an
instance of the Item structure.
1 struct Item {
2
3
var title: String
4
var content: String
5
6 }

To add an item, the user taps a button in the navigation bar. This action
instantiates an instance of the AddItemViewController class. The class
declares a didAddItem property of type DidAddItemHandler?, a type alias
for a closure that accepts an Item instance as an argument. This closure
is invoked when the user creates and saves a new item.
1 class AddItemViewController: UIViewController {
2
3
typealias DidAddItemHandler = (Item) -> ()
4
5
var didAddItem: DidAddItemHandler?
6
7
private var item: Item?
8
9
@IBAction func save(_ sender: AnyObject) {

10
11
12
13
14
15 }

if let item = item, let didAddItem = didAddItem {
didAddItem(item)
}
}

The list of items is managed by an instance of the ItemsViewController
class. This class implements the addItem(_:) action, which is linked to
the button in the navigation bar. Tapping the button instantiates the
AddItemViewController instance.
1 class ItemsViewController: UIViewController {
2
3
var items = [Item]()
4
5
@IBAction func addItem(_ sender: AnyObject) {
6
// Initialize View Controller
7
let viewController = AddItemViewController()
8
9
// Configure View Controller
10
viewController.didAddItem = { (item) in
11
// Add Item to List
12
self.items.append(item)
13
}
14
15
present(viewController, animated: true)
16
}
17
18 }

Before presenting the add item view controller, we set its didAddItem
property. The closure accepts an Item instance as its only argument and
that enables the items view controller to add the new item to the array of
items it manages. Not only removes this pattern the overhead of creating
and implementing a delegate protocol, it also keeps related code
together.

Singletons and Object References
There’s nothing wrong with object references, but it’s important to keep
track which objects know about which objects. When object references
are combined with singletons, you need to be extra careful to avoid
getting yourself onto a slippery slope.
From the moment singletons keep references to other singletons, well, I
hope by now that you know where that ends. Singletons aren’t bad, but
you need to be careful when you use the singleton pattern. I avoid it by
default and only use it when there’s no other option.

Reactive Programming
Later in this chapter, I talk about reactive programming. If you feel
comfortable using the Cocoa SDK and the Swift language, then it may be
time to look into reactive programming. It may seem daunting at first, but
it’s going to change how you think about code and software development.

Master These Patterns
Object references, delegation, and notifications are very common design
patterns on iOS, tvOS, macOS, and watchOS. The Cocoa frameworks
make heavy use of these patterns and it’s important to understand how
they work and when to use them. Even if you never define a delegate
protocol yourself, you inevitably need to use them if you build Cocoa
applications. And the same applies to notifications. And remember, this is
no rocket science.

6 Protocol-Oriented Programming
Object-oriented programming, or OOP, is a widespread paradigm most
developers are familiar with. The paradigm has been around for decades
and it’s proven its value in software development.
Because object-oriented programming is baked into the Cocoa SDK, it’s
impossible to create a Cocoa application without it. It should come to no
surprise then that it’s the default choice for most developers.
Not long after the introduction of the Swift language, a seemingly new
paradigm made its way into the Swift community, protocol-oriented
programming, or POP. What is it and should you care? Spoiler. You
should.

But First This
Before I continue, I need to tell you about Dave Abrahams. Dave works
at Apple and is a member of the Swift Core Team. A few years ago, at
WWDC 2015, Dave gave an amazing presentation that made waves in
the Swift community. In his presentation, Protocol-Oriented Programming
in Swift, Dave challenges, with a dash of humor, the defaults most of us
are used to.

I strongly encourage you to take some time to watch Dave’s presentation
about protocol-oriented programming. He does a much better job
explaining what protocol-oriented programming is and how you can
benefit from it. Dave also zooms in on some of the key driving forces of
the Swift language. Like Dave emphasizes in his talk “Swift is a protocoloriented programming language.” and “At its heart, Swift is protocoloriented.”

What Is It
Let me start with a bit of context. The idea isn’t as difficult to grasp as you
might think. Most of us are used to the obvious benefits of object-oriented
programming, such as encapsulation, access control, and inheritance.
These are features we love and usually take for granted.
The truth is that object-oriented programming comes at a cost. We pay a
price for the conveniences it offers. Object-oriented programming has its
downsides and, without realizing it, we fight them on an almost daily
basis.
What are some of those downsides? Inheritance is great, but you need to
carefully choose the superclass your class inherits from. It’s not always
clear which methods a subclass can override and which ones it should
override.
Inheritance also means that subclasses inherit stored properties from
their superclass. That’s a good thing. No? Complex class hierarchies can
add a lot of cruft to your classes, and, because Swift requires you to
provide an initial value for every stored property, initialization can be
messy.
Classes are reference types and, while this is often exactly what you
want, it can lead to complex problems that are hard to debug. Shared
mutable state often leads to complexities that bite you at some point.

Is Protocol-Oriented Programming Any Better
Protocol-oriented programming isn’t necessarily solving the shortcomings
of object-oriented programming, but it’s a better alternative in many

scenarios. Dave presents a detailed example in his presentation,
highlighting the benefit of protocol-oriented programming in Swift.
Protocol-oriented programming starts with a different mindset. Instead of
creating class hierarchies, you create types that conform to protocols. A
protocol is nothing more than an interface, defining a blueprint of
properties and methods. A type can conform to a protocol by
implementing its interface.

Flexibility
Using protocols instead of inheritance has its pros and cons. You
probably know the advantages of inheritance. What does protocoloriented programming gain us?
In Swift, a class has only one superclass while a type can conform to
multiple protocols. While value types don’t support inheritance, structs
and enums can conform to protocols.

Transparency and Abstraction
Because a protocol defines an interface, it’s immediately obvious to a
type conforming to a protocol which properties and methods it should
implement. This isn’t always true if you’re subclassing a class.
As Dave points out in his presentation, protocol-oriented programming is
often a better solution for abstraction. You can find an example of this in
Mastering MVVM With Swift. We use protocol-oriented programming to
add a layer of abstraction between the view model and the table view cell
it configures. The view model conforms to a protocol and that allows the
table view cell to configure itself with the view model without the need for
the table view cell to know about the view model’s existence, definition,
or interface.

Be Careful
While protocols may seem convenient and flexible, they can also
complicate your codebase. I’ve worked on projects that were difficult to
understand because of the overuse of protocols.

Chris Eidhof wrote about this problem a few months ago. He illustrates
the versatility of a protocol-oriented design, but he also emphasizes that
it shouldn’t be your default choice.
[P]rotocols can be very useful. But don’t start with a protocol just for
the sake of protocol-oriented programming. Start by looking at your
problem, and try to solve it in the simplest way possible. Let the
problem drive the solution, not the other way around. Protocoloriented programming isn’t inherently good or bad. Just like any
other technique (functional programming, OO, dependency injection,
subclassing) it can be used to solve a problem, and we should try to
pick the right tool for the job. Sometimes that’s a protocol, but often,
there’s a simpler way.
Remember what I wrote in the chapter on refactoring. You solve a
complex problem by implementing the simplest possible solution you can
come up with. With the problem solved, it’s time to optimize your solution.

Watch Dave’s Presentation
Don’t forget to watch Dave’s presentation. I’ve watched it several times
and you should too. It’s a fun presentation that teaches you a lot about
the Swift language, including protocol-oriented programming.

7 Reactive Programming
As a developer, you’ll have several aha moments in your career. The
discovery of reactive programming was one of those moments for me.
When I first heard about reactive programming, I was skeptical. It looked
exotic and magical, and I discarded it almost immediately. A few years
later, RxSwift crossed my path and it clicked.
It’s true that there’s a learning curve, especially if you read random
tutorials on the web. But once it clicks, you see the benefits and what
reactive programming brings to the table.

What Is It

Trying to find a definition of reactive programming that makes sense is
the first challenge you’ll face. Let’s keep it very simple and stick with
André Staltz’s definition.
Reactive programming is programming with asynchronous data
streams. — André Staltz
André has a comprehensive guide on reactive programming that you
should read if you’re interested in adopting reactive programming. As
André writes, reactive programming is nothing more than interacting with
streams of data. These are commonly referred to as observable
sequences, or observables for short.
Reactive programming isn’t built into Swift. As a result, several
frameworks and libraries have emerged for Swift and Cocoa over the
years. The most popular solutions are ReactiveCocoa and RxSwift. I’ve
chosen for RxSwift because it’s the official extension for Swift of the
ReactiveX API. It’s up to you to decide which implementation you prefer.

Why, Why, Why
As I mentioned earlier, I was skeptical when I first heard and read about
reactive programming. I didn’t see why I should invest time in yet another
technology. Objective-C and Swift had served me well for many years. It
didn’t click for me at the time. Yet reactive programming has become an
integral part of my workflow. Why is that? What changed my mind?
Simplification

Applications that respond to events, such as user interaction, tend to
become complex rather quickly. Let’s face it, asynchronous programming
isn’t easy. A request is sent to a remote API, at some point you receive a
response, and that response is used in a distant unrelated section of your
application. It can be a challenge to implement even the simplest tasks.
Reactive programming aims to make this easier. You no longer drown in
callbacks. You simply work with streams of data that you monitor,
compose, and respond to. You shift from imperative programming to
reactive programming.

Removing State

While it’s this simplification that draws most developers to reactive
programming, you receive another important benefit if you decide to
adopt reactive programming. Because you’re observing and responding
to streams of values, you no longer maintain state. Why is that
important? Why is this a big deal?
Almost every application manages state in some form or shape. If you’re
developing a mobile application, then you need to reflect some of that
state in the user interface. While this may seem easy on paper, it’s much
harder than it looks. I’m sure you know what I mean if you’re working on
projects that have a bit of complexity to them.
Reactive programming makes this much easier. For the past few months,
I’ve been working on an application with a complex timer engine. This
would have been a nightmare without reactive programming. Instead of
keeping track of the state of the timer, the time, the current segment, and
on and on, the application observes and responds to the values of
several observable sequences. It’s amazing.
Coupling

Reactive programming promotes loose coupling of objects. Any object
can observe an observable sequence and it only needs to keep a
reference to that stream of values. That’s the only aspect it’s interested
in.
The delegation pattern is very easy to replace with reactive programming.
Instead of keeping a reference to a delegate object, the delegating object
manages an observable sequence, emitting values when appropriate.
Any other object that’s interested in the values emitted by that observable
sequence can subscribe to it.
All or Nothing

Developers unfamiliar with reactive programming wrongly believe that
reactive programming requires an all-or-nothing approach. That isn’t true,
though. Once you’ve included RxSwift and RxCocoa in one of your
projects, it’s up to you to decide where, how, and why you want to use it.

The application we build in Mastering MVVM With Swift is a good
example. We only use reactive programming in a handful of classes. The
rest of the project is unaware of RxSwift and RxCocoa.

Is This For You
I encourage every developer to have a look at reactive programming.
However, if you’re new to software development, then my advice is to
focus on your foundation first. Remember what I wrote earlier in this
book. Reactive programming can wait.

Model-View-ViewModel
In Mastering MVVM With Swift, I illustrate the powerful combination of the
Model-View-ViewModel pattern and reactive programming. The ModelView-ViewModel pattern works best with a bindings solution, and reactive
programming offers just that.
Remember that it doesn’t need to be RxSwift and RxCocoa. You can use
the solution that best fits your style and preferences.

PART 2: SWIFT

1 Learn Swift With an Open Mind
Developers making the switch from Objective-C to Swift tend to translate
Objective-C into Swift. They take what they know about Cocoa
development and apply it to Swift. Unfortunately, this often results in
frustration and sometimes even an aversion towards the Swift language.
It’s easy enough to understand why developers take this approach.
People learning a new spoken language tend to look for the patterns and
constructs they’re already familiar with. While this is a common phase in
the learning process, it emphasizes the importance of a carefully chosen
learning trajectory. The same applies to picking up a new programming
language.
Developers new to Swift often take these commonalities to think that
Swift and Objective-C are very similar while they’re not.
Because Swift is so different from Objective-C, you need to take a step
backward. You need to unlearn what you know about Objective-C and
start with a clean slate and an open mind. Swift and Objective-C differ
more than they’re alike. It’s true that a Swift application runs in the
Objective-C runtime and that the languages are interoperable, they
understand one another. But developers new to Swift often take these
commonalities to think that Swift and Objective-C are very similar while
they’re not.

Reference Types and Value Types
While there’s nothing inherently wrong with classes and inheritance, Swift
implicitly encourages the use of value types (tuples, structures, and
enumerations) instead of reference types (classes). Several months ago,
I came across a talk from Andy Matuschak about this topic. It’s a great
introduction to the advantages value types have over reference types.

The Swift Standard Library also embraces value types. Strings, arrays,
dictionaries, and sets, for example, are value types in Swift. This is very
different from their Foundation counterparts, NSString, NSArray,
NSDictionary, and NSSet.

Protocol-Oriented Programming
Even though structures and enumerations in Swift are more powerful
than their Objective-C counterparts, they don’t support inheritance. This
is often seen as a missing feature and scares many developers away
from value types. Developers new to Swift and accustomed to objectoriented programming look for inheritance and find it in classes, that is,
reference types.
Earlier in the book, I emphasize that the lack of inheritance isn’t a
problem. Protocols and value types are a potent combination, maybe
even more so than reference types and inheritance.
Apple emphasizes that protocol-oriented programming is a pattern
developers should embrace in Swift. I encourage you to watch ProtocolOriented Programming in Swift to understand what it is and how you can
apply it in Swift. Dave Abrahams does a tremendous job explaining why
protocol-oriented programming is a natural fit for Swift.
Classes and inheritance remain important in Swift. They’re not the
enemy. The Cocoa frameworks are for the most part powered by
Objective-C and that means classes and inheritance are here to stay, at
least for the foreseeable future.
As a Cocoa developer, you continue to use classes and create
subclasses. But it’s equally important to understand the ideas that power
Swift and how you can use them in your projects. In his presentation,
Dave repeatedly draws attention to Swift being a protocol-oriented
language.

Type Safety
Type safety is a cornerstone of the Swift programming language. As a
developer, Swift expects you to be clear about the types of the variables
and constants you use. The advantage is that common mistakes, such as

passing a value of the wrong type to a method, can be caught by the
compiler.
Developers coming from Objective-C often struggle with Swift’s strict type
safety rules. This ties in with another concept of Swift, optionals.
Optionals are seen as an obstacle, an unavoidable side effect of Swift’s
type safety. What happened to sending messages to nil in Objective-C?
What’s wrong with that?
Optionals may indeed feel as obstacles when you first start
experimenting with Swift. As time passes and you become more familiar
with the language in its entirety, the pieces of the puzzle start to come
together and you come to appreciate optionals for what they represent
and the problem they solve. In combination with optional binding and
optional chaining, optionals start to fit into that proverbial puzzle.
I agree that optionals can feel clunky if you’re interacting with an
Objective-C API that wasn’t built with Swift or optionals in mind. But I
wouldn’t want to use Swift without them. Optionals are such a nice
feature of Swift and I’ve come to appreciate them. In fact, every time I
take a trip down memory lane when I need to fix a bug in Objective-C, I
miss them. Optionals clearly express what’s happening.
If you’re still not sure about optionals, then I suggest you read the chapter
about optionals in this book. Give them the benefit of the doubt for now.
Use them for a few weeks, avoid the exclamation mark, and see how you
feel about them in a month.

Best Practices
The more you read about Swift and the longer you spend time in the
Swift community, the more you realize that Swift is still a very young
language, especially if you compare the language with C and ObjectiveC. A common problem developers face is the lack of best practices. They
look for strategies to solve common problems and struggle to find them.
Best practices are slowly taking form as more people use the language in
real-world scenarios.
This isn’t surprising. The Swift community is still exploring the language,
finding out what’s possible and how things can or should be done. The

language is still developing at a rapid pace and the open sourcing of the
language is another component that drives this swift evolution.
Several best practices are slowly taking shape, such as the adoption of
protocol-oriented programming, the value of immutability, and the use of
value types over reference types.

Forget What You Know
My advice is to approach Swift with an open mind. Try to forget what you
know. What you know has value, but it may slow you down or it may lead
to frustration. Explore the language, become familiar with the foundations
it’s built on, and learn from others.

2 Be Critical
The primary goal of Cocoacasts is to help developers become better at
their craft. It can be challenging to put that into words. But there’s one
trait I feel every good developer should have, being critical. This means
being critical of your own work, but also of that of others.
If you spend time reading blogs, watching videos, or browsing social
media, you inevitably pick up new techniques, tips, and tricks that can
help you in your work. It’s often tempting to absorb this information as
gospel if the source is a respected developer or an authority in their field.
Even though this is a natural response, it sometimes hints at a lack of
confidence. My advice is to always be critical. The responses I get on my
tutorials and videos are most often questions. But there’s a number of
developers that send me their thoughts on the subject or they challenge
me with an alternative. That’s a healthy attitude. The reason can be
arrogance, but, more often, it’s just someone being critical.
Stack Overflow is a blessing for the developer community. I don’t think
there’s a developer that doesn’t occasionally visit Stack Overflow for
answers. But it’s important to be critical of what you read. Stack Overflow
has a reliable voting system for making sure answers are correct and
tested, but that doesn’t mean you should take what you read on Stack
Overflow as the truth.
Whenever you read a solution to a problem you’re having it’s important to
take a closer look at that solution before embracing it. Make sure you
understand the solution. Does the solution make sense? How could you
improve the solution?
The tips and practices I describe in this part have become an integral part
of my workflow. Some of them are opinionated while others are
considered good practices for Swift development. I leave it up to you to
decide whether they’re worth adopting. Remember to always be critical.

3 Embracing Optionals
Type safety is a fundamental concept of the Swift programming language
and optionals neatly tie into Swift’s strict type safety rules. The concept
underlying optionals is simple, an optional has a value or it doesn’t.
Developers new to this concept often struggle with optionals. They see
optionals as an obstacle and a direct consequence of the strict type
safety rules imposed by the language. This struggle usually dissipates
after spending some time with the language and after discovering Swift’s
constructs for safely interacting with optionals, such as optional binding
and optional chaining.

Warning Sign
Before the struggle ends, though, brute force is used to attack the
problem that optionals appear to be. After discovering the exclamation
mark, every optional is considered a nail that needs to be hit with the
proverbial hammer. Forced unwrapping and implicitly unwrapped
optionals are temporarily seen as the solution to the problem.
The exclamation mark is in Swift what you may intuitively expect it to be,
a warning sign. If you use the exclamation mark, you’re about to perform
an operation that may backfire. Forced unwrapping an optional that
doesn’t contain a value throws a runtime error, crashing your application.
The exclamation mark warned you this could happen, though.
I recently received an email from a reader about the use of the
exclamation mark. The company she works for has a simple policy,
“Don’t use the exclamation mark.” This may at times result in code that’s
a bit verbose, but the benefits are obvious. The code they write is safe
and it’s consistent.

Elegance and Beauty

The beauty of optionals is easily overlooked if not paid attention to.
Optionals embody a concept that’s easy to grasp and that’s what makes
it powerful. If you’re given a non-optional, you’re given the promise that it
has a value, it’s anything but nil. In computing, that’s a bold promise.
If you know that a constant or variable is guaranteed to have a value,
you’re also given freedom.
If you know that a constant or variable is guaranteed to have a value,
you’re also given freedom. A pointer in Objective-C, for example, isn’t
guaranteed to not be nil. While it may be pointing to a valid object now,
that may change later. No problem. You can safely send messages to nil
in Objective-C. That’s wonderful, but how often has this been an
advantage? Think about it.
If you’re sending a message to nil, it probably means that you were
expecting something to happen that didn’t happen. Is that a better
solution than optionals?
If you’re sending a message to nil, it probably means that you were
expecting something to happen that didn’t happen.

Swift to the Rescue
Swift doesn’t leave developers out in the cold. The language offers a
number of constructs for working with optionals, such as optional binding
and optional chaining.
Optional binding is used to safely unwrap the value that’s stored in an
optional. If the optional has a value, then that value is bound to a
constant that’s available in the if clause.
1 if let message = message {
2
print(message)
3 } else {
4
print("no value")
5 }

This solution is more elegant than verifying whether message has a value
and then forced unwrap the optional using the exclamation mark.

1 if message != nil {
2
print(message!)
3 } else {
4
print("no value")
5 }

Optional binding is flexible and powerful. Take a look at the following
example.
1 if let payload = payload,
2
let message = payload["message"] {
3
print(message)
4 }

Optional chaining is an elegant alternative to forced unwrapping
optionals. Instead of forced unwrapping an optional, you use optional
chaining to access a property or invoke a method on the value stored in
the optional.
1 label?.textColor = UIColor.blackColor()

The textColor property is only set if label, an optional, has a value. The
question mark is used to safely set the textColor property through
optional chaining.
At times, I use Swift’s nil-coalescing operator when I’m faced with an
optional. This can be useful to elegantly access the value of an optional
or provide a default value.
1 func date(for profile: Profile) -> Date {
2
return profile.createdAt ?? Date()
3 }

The createdAt property of the Profile instance is of type Date?. The
date(for:) function always returns a Date instance by defaulting to the
current date and time.

Embrace Optionals
Even though it may seem as if optionals are a solution to work around
Swift’s strict type safety rules, they’re complementing those rules.
Optionals get rid of unsafe pointers and offer guarantees that make your
code safer and easier to debug.

Optionals get rid of unsafe pointers and offer guarantees that make
your code safer and easier to debug.
While it may seem great that you can send messages to nil in ObjectiveC, it’s an empty promise. If you consider your application not crashing
when you send a message to a nil pointer, then think again. Also,
consider that optionals can be used for any type while nil only applies to
pointers in Objective-C.
A few days ago, I had to open up an old project that was primarily written
in Objective-C. The absence of type safety and optionals was
immediately obvious. It may sound odd, but I miss optionals every time I
need to work with Objective-C.
If you’re serious about Swift, then it’s important that you become familiar
with optionals, which problems they solve, and embrace them in the code
you write.

4 Mind the Exclamation Mark
I’m sure the exclamation mark is a necessary aspect of the Swift
language, but I wouldn’t blink an eye if it were removed from the
language tomorrow. The exclamation mark is a warning sign, but too
many developers ignore this and use it because it’s more convenient.
Note that I’m not referring to the logical NOT operator. That’s a perfectly
valid use of the exclamation mark.
As I mention later in the book, the use of the exclamation mark is often a
code smell. Because you’re trading safety for convenience, it should be
used sparingly.

Use Cases
The exclamation mark is used in several situations. The most common
use is forced unwrapping the value stored in an optional. As you know, a
runtime error is thrown if that optional doesn’t hold a value.
You also use the exclamation mark to declare an implicitly unwrapped
optional or when you want to disable error propagation. The same rule
applies. If you access the value of an implicitly unwrapped optional that
doesn’t contain a value or a throwing function throws an error when error
propagation is disabled, a runtime error is thrown.

Convenience and Laziness
Developers new to Swift often resort to the exclamation mark because
they’re unfamiliar with or confused by optionals. Most developers go
through this phase, but I always recommend to get used to optionals
sooner rather than later.
Those of us with a background in Objective-C usually have a harder time
becoming familiar with optionals. We’re used to the fact that sending
messages to nil doesn’t cause havoc in Objective-C. It does in Swift and
that’s an unwelcome change.

Don’t Be Lazy
You probably heard the phrase “A lazy developer is a good developer.”
This saying is true, but it depends on what’s understood by lazy. Many,
many developers use the exclamation mark because it’s convenient. In
other words, they’re being lazy. I’d like to say that laziness or
convenience is never a valid reason for using the exclamation mark.
Unfortunately, it’s difficult to argue with that explanation.

When I Use the Exclamation Mark
I use the exclamation mark in three situations, outlets, required
properties, and resources.

Outlets
Outlets that should always have a value are declared as implicitly
unwrapped optionals. As with every use of the exclamation mark, I only
declare an outlet as an implicitly unwrapped optional to conveniently
access its value. That’s the only reason. You can declare outlets as
optionals. That’s perfectly fine too.
If an outlet is declared as an implicitly unwrapped optional and it doesn’t
have a value when it’s accessed, then I made a mistake I need to fix.
Bear in mind that it’s possible to have optional outlets. In some projects, I
create a UIViewController class that serves as the base class for other
view controllers of the project. This class declares an optional table view
outlet. Because not every view controller has a table view, it’s wise and
necessary to declare the outlet as an optional.

Required Properties
Swift works fine with the Cocoa SDK, but there are some rough edges.
You probably know that every stored property of a class or structure
needs to have a valid initial value by the time an instance of the type is
created. This is fine, but it presents some problems if you’re working with
storyboards. If you’re using storyboards, then you’re not in charge of
instantiating the view controllers of your application. This means that you
can’t implement a custom initializer that accepts values for every stored
property.

An approach that’s often used is that you configure the destination view
controller in the prepare(for:sender:) method of the source view
controller. At that time, the destination view controller is already initialized
and every stored property has an initial value. If you want to pass a
model object to the view controller, you need to declare the property for
that model object as an optional or, you guessed it, as an implicitly
unwrapped optional.
As I mentioned earlier, the motivation for declaring a property as an
implicitly unwrapped optional is always convenience. The reasoning
behind this choice, however, is more nuanced. Let’s assume you’re
implementing a view controller that displays the details of a note. You
pass the note to the detail view controller. The detail view controller is
useless if it doesn’t have a valid note to work with. In other words, the
note property of the detail view controller should always have a value. No
exceptions.
Later in this book, I discuss fatal errors. In this situation, I prefer to throw
a fatal error if the note property doesn’t have a value because that should
never happen in production. Unfortunately, I haven’t found an elegant
solution to implement this, which is why I use implicitly unwrapped
optionals instead.

Resources
There’s one other use case in which I use the exclamation mark. If the
application needs to access a resource from its bundle, I don’t want to
deal with optionals. Why is that?
The resource, an image or a storyboard, should be present in the
application bundle. If it isn’t, then that means I have bigger problems to
worry about. Take a look at this code snippet to better understand how I
use this technique.
1 extension UIImage {
2
3
enum Icons {
4
5
enum Profile {
6
7
static let Segments = UIImage(named: "icon-profile-segme\
8 nts")
9
static let Configuration = UIImage(named: "icon-profile-\

10 configuration")
11
12
}
13
14
}
15
16 }

I also apply this technique to URLs that are hard-coded in the project.
1
2
3
4
5
6
7
8
9
10
11
12
13

enum Audio {
static let Silence = Bundle.main.url(forResource: "rocknroll", w\
ithExtension: "mp3")!
}
enum API {
static let BaseUrl = URL(string: "https://api.myawesomeapplicati\
on.co")!
}

A Personal Choice
While it’s a personal choice when you use the exclamation mark and
what your motivation is, it’s important that understand why you’re using
the exclamation mark and what the consequences are. The next time you
append an exclamation mark to a variable, consider your motivation and
the risk. Choose wisely and don’t be lazy.

5 Exclamation Marks and Fatal Errors
Fatal errors have a negative connotation and with reason. You should
use them sparingly if you want to avoid having your application crash and
burn at the slightest hiccup. Despite their negative undertone, fatal errors
are an integral part of my workflow as I write elsewhere in this book.
Whenever I write or speak about my use of fatal errors, I usually see two
types of responses. Developers unfamiliar with fatal errors and how they
can be used safely are surprised and excited. They spot the benefits fatal
errors can bring to a project. Can you guess what the second type of
response sounds like?
Why don’t you use an exclamation mark instead?
The suggestion to use an exclamation mark instead of throwing a fatal
error is understandable. From a user’s perspective, the result is identical.
But I’m not using fatal errors with the user in mind. I don’t throw a fatal
error to crash the application when the user is using it. In an ideal
scenario, a fatal error should only be thrown in development or when the
application is being tested.
I agree that the user won’t appreciate my use of fatal errors if the
application crashes the moment they’re about to best their previous high
score. The thing is that I’m a developer and I look at code most of my
working hours. And that’s exactly the reason I choose for fatal errors
more frequently than I choose for the exclamation mark. Let me explain
what I mean by that.

Clarity Over Subtleness
My biggest complaint with the exclamation mark is its subtleness.
Ironically, plenty of developers use the exclamation mark for exactly that
reason. It’s so easy to append an exclamation mark to a variable or a
constant. It’s almost too easy. I understand why the Swift team has

chosen to support forced unwrapping and forced conversion using the
as! operator, but I wouldn’t shed a tear if both were removed from the
Swift language tomorrow.
I agree that it can be frustrating to interact with an ancient Objective-C
API that doesn’t care about nil and optionals. Interacting with the file
system, for example, can often lead you down a rabbit hole of optionals,
indentation, and conditionals. But that’s what it takes if you decide to
write software in Swift.
Don’t be lazy by appending an exclamation mark to a variable or a
constant you’re pretty sure will always contain a value. It will contain a
value … most of the time … almost always. As the documentation
explains, you should only force unwrap an optional if you’re certain that it
contains a value. I turn it around when I use fatal errors. A fatal error
should be thrown if the application enters a state it didn’t anticipate.

Choosing for Clarity
A common trait among developers is an obsession with simplicity and
minimalism. Clean code is but one manifestation of this trait. By using
fatal errors I choose for clarity. If the application throws a fatal error, I
want to know about it. It’s true that the exclamation mark will also do that
for me. But I also want to know about it when I’m simply reading through
my code.
An exclamation mark doesn’t jump out, but a guard statement with a
fatalError() call does. It immediately shows you that you know that a
certain scenario should never happen and you guard against that.
Take a look at the following implementation of the prepare(for:sender:)
method. This is a common pattern I use. If the user triggers the
Segue.SelectProfile segue, the application expects the destination view
controller to be of type SelectProfileViewController. It simply doesn’t
know how to respond if that isn’t true hence the fatal error in the else
clause of the guard statement. While it may look a bit verbose, it’s clear
and explicit.
1 // MARK: - Navigation
2
3 override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

4
guard let identifier = segue.identifier else { return }
5
6
switch identifier {
7
case Segue.SelectProfile:
8
guard let destination = segue.destination as? SelectProfileV\
9 iewController else {
10
fatalError("Unexpected Destination View Controller for S\
11 egue")
12
}
13
14
...
15
default: break
16
}
17 }

The alternative is to use the as! operator to forcefully convert the
destination view controller to the type the application expects.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

// MARK: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let identifier = segue.identifier else { return }
switch identifier {
case Segue.SelectProfile:
let destination = segue.destination as! SelectProfileViewCon\
troller
...
default: break
}
}

I understand that this practice is a bit controversial, but I’ve seen its
effectiveness. It’s why I’m a big fan of this pattern. As I mentioned earlier
in this chapter, the issue I have with the exclamation mark is that it isn’t
explicit enough, it’s too subtle. It’s easy to overlook it while browsing a
codebase.
The difference between the use of fatal errors and the use of the
exclamation mark is subtle. You could also say that the difference is easy
to miss, which is exactly why I bring it up. Give it a try and let me know
what you think.

6 Smelly Code
Pixelsync was the first iOS application I published on the App Store. For
a first project, it was quite complex and far more challenging than I had
anticipated. The project grew quickly as I added more features and
maintainability quickly became an issue I couldn’t ignore.
Looking back, the project was littered with anti-patterns, bad practices,
and code smells. Adding features to a large, complex codebase is
challenging if it lacks direction and structure.
Many developers start out this way and learn as they go. It’s fine to make
mistakes as long as you learn from your mistakes and find solutions that
work better. In this chapter, I want to focus on common signs of code
smell in Swift.

Forced Unwrapping and Conversion
Once you get used to optionals, you come to appreciate their value. Not
only are optionals making your code safer, they also make your code
more readable. An optional carries a message that says “I may not have
a value. Be careful.”
Developers new to Swift often see optionals as a hurdle, forcing them to
jump through a bunch of unnecessary hoops. Optionals need to be
unwrapped and that requires more code. There’s a shortcut, though. It’s
possible to forced unwrap optionals. Take a look at the following
example.
1
2
3
4
5
6

private func profileData(for launchOptions: [UIApplicationLaunchOpti\
onsKey: Any]?) -> [ProfileData]? {
let fileUrl = launchOptions![UIApplicationLaunchOptionsKey.url] \
as! URL
return profileData(at: fileUrl)
}

This looks fine. Right? We’re certain that the dictionary of launch
optionals isn’t equal to nil, that the UIApplicationLaunchOptionsKey.url

is present, and that its value is of type URL.
It doesn’t matter how certain you are, an optional should be treated with
caution. Forced unwrapping or forced conversion is asking for trouble. As
I discussed in an earlier chapter, there are situations in which you can
use the ! operator, but do not forced unwrap an optional to avoid a guard
or an if statement or a few extra lines of code.
The updated example shows you how the guard statement can elegantly
and safely handle optionals. The guard statement tells us what we
expect, but, at the same time, it hints that we may not get what we
expected.
1
2
3
4
5
6
7
8
9
10
11
12
13

private func profileData(for launchOptions: [UIApplicationLaunchOpti\
onsKey: Any]?) -> [ProfileData]? {
guard let launchOptions = launchOptions else {
return nil
}
guard let fileUrl = launchOptions[UIApplicationLaunchOptionsKey.\
url] as? URL else {
return nil
}
return profileData(at: fileUrl)
}

If you find yourself using a ! instead of an ?, then stop for a moment
and ask yourself whether there’s a safer alternative.

Monster Classes
Andy Matuschak is a great speaker and a very good teacher. He once
gave a wonderful talk at the Realm offices about refactoring view
controllers. In the talk, Andy illustrates that view controllers are often
taking on far too many responsibilities.
Some of us apply the Model-View-Controller pattern a bit too strictly. Did
you know that it’s fine to create classes that are not models, views, or
controllers?
Some developers even argue that you should create fat models and
skinny controllers. While that may be a bit too much responsibility for the
model layer, I agree that controllers should be lean and lightweight. Of

course, it’s easy to stuff business logic in controllers and it takes a bit of
extra work to refactor code that can belong in a separate class. But it’s
often the right choice.
By isolating functionality, you put the view controllers of your project on a
diet and make code easier to reuse. Why not extract a piece of
functionality in an Objective-C category or a Swift extension.
If the implementation of a class exceeds 1000 lines of code, I know it’s
time for a serious round of refactoring. Can you load 1000 lines of code in
your working memory? That’s what it takes to work with a class. If you
make changes to a class, you need to know how other parts are affected
and that’s only possible if you know what the various parts of the class
do.

Massive Methods
Monster classes very often harbor massive methods. Few things in a
developer’s life are as frustrating as unit testing a method that spans
dozens and dozens of lines. As I mention elsewhere in the book,
functions and methods should be focused and to the point. A function or
method should ideally have a singular focus.

Helper Methods
Most of my view controllers have a handful to a dozen helper methods.
These helper methods are focused and help other methods be the same.
Do the viewDidLoad() methods of your view controllers span dozens and
dozens of lines? That’s a code smell.
I diligently try to keep methods short and succinct. Every view controller I
implement that has any complexity to it has a setupView() and a
updateView() method. I use these methods to factor any view
configuration out of the viewDidLoad() method into these helper methods.
1 // MARK: - View Life Cycle
2
3 override func viewDidLoad() {
4
super.viewDidLoad()
5
6
// Set Title
7
title = NSLocalizedString("root_view_title", comment: "Root View\
8 Title")
9

10
11
12
13
14
15 }

// Setup View
setupView()
// Setup Notification Handling
setupNotificationHandling()

Property Observers
Configuring views isn’t my favorite pastime. To remedy this, I often add a
didSet property observer to an outlet to configure it when it’s set. There
are several benefits, one of them being that it keeps the configuration
close to the outlet’s declaration.
1 @IBOutlet var messageLabel: UILabel! {
2
didSet {
3
messageLabel.numberOfLines = 0
4
messageLabel.font = UIFont.Namaste.lightRegular
5
messageLabel.textColor = UIColor.Namaste.lightGray
6
messageLabel.text = NSLocalizedString("root_message_no_profi\
7 les", comment: "")
8
}
9 }

I’m sure several developers frown when they see this pattern in the wild.
While I’m not sure, I believe I learned this trick from Natasha Murashev.
Credit where credit is due.

Ambiguous Method Names
Massive methods aren’t only hard to unit test, they almost always have
names that make little or no sense. Because massive methods perform a
slew of tasks, it’s difficult to name them.
Massive methods usually have long names that don’t reflect the
implementation or they have a vague name that could mean anything.
Break the method up into smaller, focused methods and give each a
descriptive name. This small change immediately improves the testability
of massive methods.

Ignoring Errors
It’s great to see that error handling is tightly integrated into the Swift
language. In Objective-C, it’s easy to ignore errors, a bit too easy if you
ask me. Have you ever seen something like this?
1 [managedObjectContext save:nil];

I don’t know any developer who enjoys error handling, but if you want to
write code that works and applications that can recover when things go
haywire, then you need to accept that error handling is part of the job.
Ignoring errors also makes debugging more difficult. Putting your head in
the sand isn’t the solution when things go wrong. Don’t worry, though.
Later in this book, we explore error handling in a bit more detail.

Singletons
Singletons are great. They’re so useful that less experienced developers
tend to overuse them. Been there, done that. I’m not joking when I say
that singletons are great. Even though I don’t consider the singleton
pattern an anti-pattern, sometimes it seems as if developers have
forgotten how to pass an object by reference.
One of the negative side effects of singletons is tight coupling. Over the
years, I have come across projects that were littered with singletons,
singletons referencing other singletons. This can make refactoring a
nightmare.
After removing the singletons from a project, it’s no longer intimidating,
and it loses some of its complexity. By passing objects by reference,
even if only one instance is alive at any one time, it becomes much
clearer where the object is used and what role it plays.
Another benefit of keeping singletons to a minimum is testing. Singletons
make testing more difficult.
There’s nothing wrong with passing objects by reference. Whenever
you’re about to create a singleton, ask yourself whether passing the
object by reference is an option. That should be your first choice. Always.

String Literals
String literals are smelly by default. They’re great in playgrounds, but how
often do you, or should you, use string literals in a project? The only valid
use cases I can think of are localization, constants, and logging.
I agree that creating constants or enums is tedious, but it pays off in the
long run. You avoid typos, autocompletion kicks in, and it significantly

improves maintainability.
This certainly isn’t a hard rule that I apply to the projects I work on, but I
try to stick to it as much as possible. If the value of an object literal is
used in more than one place, it’s defined as a constant or enumeration,
or, even better, put in a configuration file.
My Xcode color scheme highlights string literals in bright red. When I’m
browsing through lines and lines of code, the string literals stand out
immediately. If I see too much red, it’s time for a clean-up.

String literals are highlighted in bright red.

Is Your Code Smelly
As I mentioned earlier, the goal of this chapter is to review the code you
write. How can I improve this? What side effects does this
implementation have? Should I forced unwrap this optional? It rarely pays
off to take a shortcut.

7 Value Types and Reference Types
When talking about object-oriented programming, most of us intuitively
think about classes. In Swift, however, things are a bit different. While
you can continue to use classes, Swift has a few other tricks up its sleeve
that can change the way you think about software development. This is
probably the most important shift in mindset when working with Swift,
especially if you’re coming from a more traditional object-oriented
programming language like Ruby or Objective-C.

What’s the Fuss
The concept we tackle in this chapter is the differences between value
types and reference types or, put differently, passing by value and
passing by reference.
In Swift, instances of classes are passed by reference. This is similar to
how classes are implemented in Ruby and Objective-C. It implies that an
instance of a class can have several owners that share a copy.
Instances of structures and enumerations are passed by value. Every
instance of a struct or enum has its own unique copy of data. And the
same applies to tuples.
In the remainder of this chapter, I refer to instances of classes as objects
and instances of structs and enums as values. This avoids unnecessary
complexity.

An Example
It’s important that you understand the above concept so let me explain
this with an example.
1 class Employee {
2
3
var name = ""
4
5 }
6

7
8
9
10
11
12
13
14

var employee1 = Employee()
employee1.name = "Tom"
var employee2 = employee1
employee2.name = "Fred"
print(employee1.name) // Fred
print(employee2.name) // Fred

We declare a class, Employee, and create an instance, employee1. We set
the name property of employee1 to Tom. We then declare another variable,
employee2, and assign employee1 to it. We set the name property of
employee2 to Fred and print the names of both Employee instances.
Because instances of classes are passed by reference, the value of the
name property of both instances is equal to Fred. Does that make sense or
does the result surprise you?
1
2
3
4
5
6
7
8
9
10
11
12
13
14

struct Employee {
var name = ""
}
var employee1 = Employee()
employee1.name = "Tom"
var employee2 = employee1
employee2.name = "Fred"
print(employee1.name) // Tom
print(employee2.name) // Fred

In the second example, we declare a structure, Employee, and repeat the
steps of the first example. The output of the print statements is different,
though.
By replacing class with struct, the outcome of the example changes in a
significant way. An instance of a class, an object, can have multiple
owners. An instance of a struct has one owner. When an instance of a
struct is assigned or passed to a function, its value is copied. A unique
instance of the struct is passed instead of a reference to the instance of
the struct.
The moment employee1 is assigned to the employee2 variable, a copy of
employee1 is made and assigned to employee2. The values of employee1
and employee2 have no relation to one another apart from the fact that
they are copies.

Benefits of Value Types
Swift uses value types extensively. Strings, arrays, dictionaries, sets, and
numbers are value types in Swift. That’s no coincidence. If you
understand the benefits of value types, you automatically understand why
these types are defined as value types in Swift’s standard library. What
are some of the benefits of value types?

Storing Immutable Data
Value types are great for storing data. And they are even better suited for
storing immutable data. Assume you have a struct that stores the
balance of the user’s bank account. If you pass the balance to a function,
that function doesn’t expect the balance to change while it’s using it. By
passing the balance as a value type, it receives a unique copy of the
balance, regardless of where it came from.
Knowing that a value won’t change is a powerful concept in software
development. It’s a bold promise and, if used correctly, one that value
types can keep.

Manipulating Data
Value types usually don’t manipulate the data they store. While it is fine
and useful to provide an interface for performing computations on the
data, it’s the owner of the value that manipulates the data stored by the
value.
This results in a control flow that is transparent and predictable. Value
types are easy to work with and, another great benefit, they behave
admirably in multithreaded environments.
Why is that? If you fetch data from a remote API on a background thread
and pass the data, as a value, from the background thread to the main
thread, a copy is made and sent off to the main thread. Modifying the
original value on the background thread won’t affect the value that’s
being used on the main thread. Clean, simple, and transparent.

When to Use Value Types

While I hope I’ve convinced you to start using value types more often,
they’re not a good fit for every scenario. Value types are great for storing
data. If you pass around the balance of someone’s account in your
application, you shouldn’t be using a class instance. What you are doing
is passing around a copy of the current balance of the account.
But if you need to pass around the account itself, then you want to make
sure the objects that have a reference to the account are working with the
same account, the same instance. If the name of the account holder
changes, you want the other objects that have a reference to the account
to know about it.
Value types and reference types each have their value and use. It would
be unwise to choose one over the other. Andy Matuschak has a clear
stance on the benefits of value types and reference types in software
development and has given several presentations on the topic. Andy
describes the objects of an application as a layer that operates on the
value layer. That’s a great way to put it.
Think of objects as a thin, imperative layer above the predictable,
pure value layer. — Andy Matuschak

8 Catching Errors
I was thrilled to find out that error handling is built into the Swift language.
As I wrote earlier, it’s too easy to ignore errors in Objective-C. You can
still ignore errors in Swift if you choose to go that route, but you need to
be explicit about it.
This chapter won’t repeat what The Swift Programming Language has to
say about error handling in Swift. Instead, I’d like to take the opportunity
to give you some tips about error handling. When should you handle
errors? Should you always notify the user if something goes haywire?
Where should you handle errors?

When Should You Handle Errors
The short answer is simple. Always. The answer is more nuanced,
though. The remainder of this chapter zooms in on the when, the how,
and the why.

Where Should You Handle Errors
Error handling in Swift is intuitive and flexible. You can propagate errors
and handle them where it feels appropriate. The question is then, “Where
is it appropriate to handle errors?” The rule I apply in most scenarios is
simple and easy to adopt. Whenever an object performs an operation
and an error is thrown, the error is handled by the object that still
understands what the error is about. Let me explain what I mean by this
with an example.
A few days ago, I was implementing receipt validation in one of my
applications. I won’t go into the finer details, but suffice to say that the
application sends the receipt to a remote server, which validates the
receipt, and returns a response to the application. The response is a
JSON object that is deserialized using John Sundell’s fantastic Unbox
library.

As you can imagine, things can go wrong in several phases of the
operation. Which objects should handle which errors? The object that
deserializes the JSON response should handle any errors that are thrown
by the deserialization operation. It isn’t useful to propagate these errors
since the objects upstream won’t understand the errors and, more
importantly, don’t need to know about them.
If you do want to notify the objects upstream, then I suggest defining and
throwing a custom error. This can be very useful to summarize a range of
errors that an upstream object can understand and respond to.
Another example involves Core Data. I always use a dedicated object to
manage the application’s Core Data stack. This object handles any errors
that are thrown by a save operation. If other objects need to know about
a failed save operation, a custom error is thrown by the Core Data
manager.
Objects that are unaware of the persistence layer, Core Data in this
example, won’t know how to handle the errors that a managed object
context can throw. They can at best check if any errors are thrown by a
managed object context. It usually doesn’t make sense to make an object
handle errors it doesn’t understand or doesn’t know how to respond to.

Notifying the User
Developers new to programming or Swift development usually choose
one of two strategies when handling errors. The either ignore errors
altogether or they print any errors that pop up to the console. Neither
approach is ideal, but the latter group is at least informed when
something goes wrong.

User Action
Many operations can go wrong or backfire. When should you notify the
user? Let’s start with the most obvious scenario. When the user performs
an action that backfires, she should be notified that her action was
unsuccessful.
Is this a hard rule? No. If the user likes a post on Facebook and the API
request was unsuccessful, you may only want to notify her if she’s still on

the page she liked. If the failed API request is the result of a poor network
connection, then that would mean the user is notified after the network
request timed out. That may be too late for the user to make sense of the
error.

Background Operations
Most applications perform background operations the user isn’t, and
shouldn’t be, aware of. Examples include data synchronization and
receipt validation. Should you notify the user if your application is unable
to synchronize the user’s database? The answer is almost always no.
This doesn’t mean the user shouldn’t be informed, though.
What I like about 1Password’s mobile application, for example, is the
current state of the synchronization process as well as the last time the
application synchronized.

1Password

If something goes funky, the user can read about it in the settings of the
application.

Avoid Cryptic Messages
I’m sure you’ve seen error messages with a cryptic message or error
code. You should avoid this at any cost. It doesn’t help the user to see an
alert with an HTTP status code. In fact, it may concern and annoy the
user.

Monitoring Application Health
The downside of mobile applications is that you can’t easily monitor your
application’s performance or health in real time. This is very different for
web applications.
How are you going to stay informed about your application’s performance
and health the moment it’s in the hands of your customers? Are you
going to wait until your customers email you? We cover this in more
detail later in the book. For now, I want to emphasize that you need eyes
on your application from the moment your application is in production.
How often does your application crash? Which errors occur most often?
What is the cause of these errors?

Don’t Ignore Them
I think that knowing how, when, and where to handle errors is what stops
many inexperienced developers from handling errors properly. There is
no clear-cut recipe for error handling and that can be frustrating. The
guidelines I present in this chapter should give you a better idea where to
start and I hope it’s clear that you shouldn’t ignore errors.

9 Using Fatal Errors to Write Elegant Swift
Speaking of errors, a few months ago I stumbled on a discussion in the
thoughtbot guides about the use of fatal errors in Swift. It seems every
developer has an opinion about fatal errors and a consensus hasn’t been
reached yet in the Swift community. The only mention in The Swift
Programming Language is in the section that discusses the guard
statement and early exit.
When I first encountered the fatalError(_:file:line:) function, it
reminded me of the abort() function. Even though both functions cause
the immediate termination of your application, the
fatalError(_:file:line:) function is different and, in the context of Swift,
it’s more useful.

What to Do When You Don’t Know What to Do
Ever since I started working with Swift, I’ve been struggling with the
implementation of the tableView(_:cellForRowAt:) method. If you think
that sounds silly, then take a look at the following example.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

override func tableView(_ tableView: UITableView, cellForRowAt index\
Path: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: Sett\
ingsTableViewCell.reuseIdentifier, for: indexPath) as? SettingsTable\
ViewCell {
// Configure Cell
cell.textLabel?.text = "Some Setting"
return cell
} else {
return UITableViewCell()
}
}

There are several variations of the above implementation and I’ve tried all
of them. The idea is simple. We expect an instance of the
SettingsTableViewCell class if we ask the table view for a cell with the
reuse identifier of the SettingsTableViewCell class. Because the
dequeueReusableCell(withIdentifier:for:) method returns a

UITableViewCell instance, we
SettingsTableViewCell class.

need to cast the result to an instance of the

This is inconvenient since we always expect to receive a
SettingsTableViewCell instance if we ask the table view for a cell with the
reuse identifier of the SettingsTableViewCell class. We could use the as!
operator instead of the as? operator, but that isn’t a solution I feel
comfortable with. Remember that I avoid the exclamation mark whenever
I can.
If for some reason, something goes wrong, we return a UITableViewCell
instance from the tableView(_:cellForRowAt:) method. But that should
never happen. Right?
While this is fine and necessary to make sure we return a
UITableViewCell instance from the tableView(_:cellForRowAt:) method, I
hope you can see that we’re implementing a workaround for a scenario
we don’t expect, a scenario that should never occur.

Guarding Against Unexpected Events
Every time I implement tableView(_:cellForRowAt:) I wonder if there’s a
better approach. And there is. We need to guard against the event that
the table view hands us a UITableViewCell instance we don’t expect and,
if that happens, we throw a fatal error.
1
2
3
4
5
6
7
8
9
10
11
12
13

override func tableView(_ tableView: UITableView, cellForRowAt index\
Path: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: S\
ettingsTableViewCell.reuseIdentifier, for: indexPath) as? SettingsTa\
bleViewCell else {
fatalError("Unable to Dequeue Reusable Cell")
}
// Configure Cell
...
return cell
}

The application crashes if a fatal error is thrown. Why is this better? This
is a better solution for two reasons.

Unexpected State

If the application runs into a scenario in which a fatal error is thrown, we
communicate to the runtime that the application is in a state it doesn’t
know how to handle.
In the first example, the solution was to return a UITableViewCell
instance. Does that solve the problem? No. The application ignores the
situation and avoids causing havoc by returning a UITableViewCell
instance. The application avoids dealing with the unexpected state it’s
gotten itself into.

Finding and Fixing the Bug
If the application runs into a state we didn’t anticipate, it means a bug has
slipped into the codebase. If the application is terminated due to a fatal
error being thrown, we have work to do. It means that we need to find the
bug and fix it.
The above solution, using a guard statement and throwing a fatal error, is
a solution I’m very happy with. It avoids the obsolete if statement of the
first implementation of the tableView(_:cellForRowAt:) method and it
correctly handles the situation. The result is a much more elegant
implementation of the tableView(_:cellForRowAt:) method. And it adds
clarity to the implementation of the tableView(_:cellForRowAt:) method.

Use Fatal Errors Sparingly
This doesn’t mean that you need to use fatal errors whenever you want
to avoid error handling or the application enters a state that’s hard to
recover from. I use fatal errors only when the application can enter in a
state it wasn’t designed for. Take a look at the following example.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

import Foundation
enum Section: Int {
case news
case profile
case settings
var title: String {
switch self {
case .news: return NSLocalizedString("section_news", comment\
: "news")
case .profile: return NSLocalizedString("section_profile", c\
omment: "profile")
case .settings: return NSLocalizedString("section_settings",\

16 comment: "settings")
17
}
18
}
19
20 }
21
22 struct SettingsViewViewModel {
23
24
func title(for section: Int) -> String {
25
guard let section = Section(rawValue: section) else {
26
fatalError("Unexpected Section")
27
}
28
return section.title
29
}
30
31 }

The title(for:) method of the SettingsViewViewModel struct doesn’t
expect a value it can’t use to instantiate a valid Section instance with. If
the value of the section parameter is invalid, it wouldn’t know what to do.
In that scenario, a fatal error is thrown.
If the application does enter that scenario, it means you made a logical
mistake and it’s your task to find out why and how it can be resolved.

Clarity and Elegance
The use of the fatalError(_:file:line:) function has made my code
more readable without compromising the inherent safety of the Swift
language. It adds clarity to the code I write and Swift regains its
elegance. Give it a try and let me know if you like it.

PART 3: PROJECTS

1 A Brand New Project
There are many tutorials and courses available to get started with Swift
development. The issue with most of them is that they’re focused on a
specific topic, ignoring other essential aspects of Swift development.
What teachers often forget is that developers new to a language, a
framework, or a technology, are very, very receptive to new information.
This includes best practices, but, unfortunately, it also means less good
practices or even bad habits.
In this chapter, I’d like to walk you through the steps I take when setting
up a brand new project in Xcode 9. By following the steps laid out in this
chapter, you set yourself up for a successful project. Let it sink in and
tweak it to your own preferences.

Step 1: Setting Up the Project
I understand that it can be useful to experiment from time to time, but I
always use the Single View App template for new projects. It gives me
an application delegate, a view controller, and a storyboard. I don’t need
anything else when I’m starting a new project.

Choosing a Template

Give the project a sensible name and check Include Unit Tests and
Include UI Tests. I never check Use Core Data for production projects.

Configuring the Project

While it may seem convenient to check Create Git repository on my
Mac, I don’t recommend this. Why is that? The project first needs a bit of
housekeeping before I’m ready for my first commit, Xcode doesn’t
automatically add a .gitignore file, and I don’t like Xcode’s first commit
message. The latter is obviously a nitpicky detail.

Choosing a Location for the Project

Step 2: Organizing the Project

I always start by cleaning up the project. This simply means putting the
application delegate in a separate group, organizing the view controllers,
and making sure no files live at the root of the project. Small projects
don’t have the problem of becoming cluttered, but large projects do, and
very quickly at that.
The idea is simple. This is the project Xcode has created for us.

Before Organizing the Project

And this is the project after adding some structure. Later in this book, I
take a closer look at organizing a project in Xcode and how to use groups
and folders to keep everything nice and tidy.

After Organizing the Project

Step 3: Adding a README.md
Even if you’re working in a team of one, it can be very helpful to
document your project and it’s something I strongly recommend. If you’ve
ever browsed GitHub, then you probably know that putting a file named
README.md at the root of the project is a good first step. Markdown is a
wonderful markup language and it’s ideal for this purpose. This is the
README.md file I usually start with.
1
2
3
4
5
6
7
8
9
10
11
12
13

# Project Name
## Author: Bart Jacobs
### Description: Lorem ipsum dolor sit amet, consectetur adipiscing \
elit. Curabitur ac dolor justo, ac tempus leo. Etiam pulvinar eros a\
t lectus sollicitudin scelerisque. Aliquam erat volutpat. Suspendiss\
e eu eros non elit blandit suscipit. Morbi scelerisque euismod tempu\
s.
### Dependencies:
- Unbox
- RxSwift
- RxCocoa
- Reveal

If you’re working in a team, then I recommend putting more time and
effort into documenting the project. I discuss this in more detail elsewhere
in the book.

Step 4: Build and Run
Before I put the project under source control, I make sure it builds and
runs without warnings and errors. After updating the project’s structure, it
sometimes happens that Xcode can no longer find some of the files you
moved. We need to fix this before we put the project under source
control. As I mention in the chapter on source control, you should only
make a commit if the project builds successfully, without warning and
errors.

Step 5: Adding a .gitignore
Before we put the project under source control, we need to add a
.gitignore file. If you’re unfamiliar with Git and the purpose of a
.gitignore file, then I recommend reading more about this fantastic
version control system.

The .gitignore file at the root of the project defines which files need to be
kept under source control and which files can be ignored hence the name
of the file. This is what the .gitignore file of most of my projects looks
like.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

#########################
# **.gitignore** file for Xcode4 / OS X Source projects
#
# NB: if you are storing "built" products, this WILL NOT WORK,
#
and you should use a different **.gitignore** (or none at all)
# This file is for SOURCE projects, where there are many extra
#
files that we want to exclude
#
# For updates, see: http://stackoverflow.com/questions/49478/git-ign\
ore-file-for-xcode-projects
#########################
#####
# OS X temporary files that should never be committed
.DS_Store
*.swp
profile

####
# Xcode temporary files that should never be committed
#
# NB: NIB/XIB files still exist even on Storyboard projects, so we w\
ant this...
*~.nib

####
# Xcode build files #
# NB: slash on the end, so we only remove the FOLDER, not any files \
that were badly named "DerivedData"
DerivedData/
# NB: slash on the end, so we only remove the FOLDER, not any files \
that were badly named "build"
build/

#####
# Xcode private settings (window sizes, bookmarks, breakpoints, cust\
om executables, smart groups)
#
# This is complicated:
#
# SOMETIMES you need to put this file in version control.
# Apple designed it poorly - if you use "custom executables", they a\
re
# saved in this file.
# 99% of projects do NOT use those, so they do NOT want to version c\
ontrol this file.
# ..but if you're in the 1%, comment out the line "*.pbxuser"

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

*.pbxuser
*.mode1v3
*.mode2v3
*.perspectivev3
#
NB: also, whitelist the default ones, some projects need to use\
these
!default.pbxuser
!default.mode1v3
!default.mode2v3
!default.perspectivev3

####
# Xcode 4 - semi-personal settings, often included in workspaces
#
# You can safely ignore the xcuserdata files - but do NOT ignore the\
files next to them
#
xcuserdata
####
# XCode 4 workspaces - more detailed
#
# Workspaces are important! They are a core feature of Xcode - don't\
exclude them :)
#
# Workspace layout is quite spammy. For reference:
#
# (root)/
#
(project-name).xcodeproj/
#
project.pbxproj
#
project.xcworkspace/
#
contents.xcworkspacedata
#
xcuserdata/
#
(your name)/xcuserdatad/
#
xcuserdata/
#
(your name)/xcuserdatad/
#
#
#
# Xcode 4 workspaces - SHARED
#
# This is UNDOCUMENTED (google: "developer.apple.com xcshareddata" -\
0 results
# But if you're going to kill personal workspaces, at least keep the\
shared ones...
#
#
!xcshareddata
####
# XCode 4 build-schemes
#
# PRIVATE ones are stored inside xcuserdata
!xcschemes
####
# Xcode 4 - Deprecated classes
#
# Allegedly, if you manually "deprecate" your classes, they get move\
d here.
#

121
122
123
124
125
126
127

# We're using source-control, so this is a "feature" that we do not \
want!
*.moved-aside
# CocoaPods
/Pods

As you can see it includes references to Xcode 4, which shows you how
long I’ve been using this .gitignore file. It works well for me. While most
of the contents are easy to understand, there are a few details that are
worth pointing out.
At the bottom, you can see a reference to CocoaPods, the dependency
manager of my choice. The /Pods entry means that I ignore the entire
Pods directory. This is a personal choice and it has its pros and cons.
I’ve never run into the cons, which is why I’ve stuck with this option.
While ignoring the Pods directory is fine and up to you to decide, you
should never ignore Podfile.lock or, if you’re using Carthage,
Cartfile.lock. As the extension of the file implies, a lock file locks the
current configuration. A project’s Podfile or Cartfile describes the
project’s dependencies, optionally specifying the version that should be
used. The project’s Podfile.lock or Cartfile.lock locks the current
configuration, including the version that is used by the project.
Putting lock files under source control is especially important if you’re
working in a team. When a team member checks out the repository and
installs the project’s dependencies by running pod install or carthage
bootstrap, you want to make sure they’re including the correct version of
each dependency.
The .gitignore file also defines that I ignore any personal preferences
and settings. This is recommended for teams. You don’t want to clutter
the repository with the preferences of every team member that worked on
the project.
To be clear, I didn’t create this .gitignore file from scratch. I don’t recall
where I picked it up, but it’s important to be critical of things you pick up
from elsewhere. Make sure you understand every line of the .gitignore
file you use in your projects.

Step 6: Putting the Project Under Source Control
The most popular version control system in the Cocoa and Swift
communities is Git. It’s a wonderful piece of software with many features
and it’s easy to get started with. This book won’t cover the details of Git,
but there are plenty of resources to get up to speed quickly. I reference a
few of them in the chapter on source control.
When I wrote my first lines of code many moons ago, I didn’t know about
source control and discovering Git was a true revelation. It was one of
those aha moments. It felt incredible.
It’s surprising to see that there are still developers that don’t use any type
of source control. If that’s you, don’t be embarrassed. But take a moment
to learn the basics of Git (or any other version control system) and take
your work seriously. You don’t want to lose any work by not using source
control.
The steps I take to put the project under source control are always the
same. Take a look at the following commands. That’s all it takes to get
started with Git.
1 git init
2 git add .
3 git commit -m "Project setup"

Step 7: Pushing the Project to GitHub
I very much enjoy using GitHub and, to make sure my work is safe, I
create a private repository and push the project to GitHub. You can use
other solutions as well, such as Bitbucket or GitLab. Once you’ve created
the repository on GitHub, you only need to add it as a remote and push
the repository.
1 git remote add origin 
2 git push origin master

Step 8: Optional Steps
You can take it a few steps further and, if you’re working in a company,
that may be necessary. These steps usually include adding a Gemfile,

setting up continuous integration or creating a project in a management
tool. These steps are optional, though.

2 Project Structure
The application templates that ship with Xcode aren’t the best examples
for developers new to Cocoa development. A new project in Xcode isn’t
structured in any way and the project folder on disk isn’t either. This isn’t
an approach that scales and it’s not something I can recommend.
One of the subtle details students appreciate about my books and
courses is that they see what a production project can look like. Can not
should. I believe it’s important to stick to a set of guidelines to make sure
you introduce consistency and structure into your projects.
That’s probably what I appreciated most when I created my first Ruby on
Rails application. David Heinemeier Hansson emphasizes that Ruby on
Rails is an opinionated framework providing sensible defaults. Such an
approach has its pros and cons. A definite upside is that a Ruby on Rails
application expects a particular project structure. Developers new to
Ruby on Rails like this, but I can imagine that more experienced
programmers develop their own opinions over time.
I’m sure you agree that any structure is better than no structure. The
approach I use has evolved over the years. For example, when I started
to adopt the Model-View-ViewModel pattern in my projects, I made a few
tweaks to my projects’ structure. That’s fine. The core idea is to be
consistent and to have a project structure that works for you and your
team.

An Example
The projects I include in my courses and books are relatively basic
compared to the production projects I work on. For that reason, I’d like to
give you a peek behind the scenes of one of my recent projects. Every
project I create and work on adopts this project structure. It works for me,
but I understand that other solutions work equally well. Remember that
consistency is key.

A project structure that works.

As I wrote in the previous chapter, the first thing I do when I create a new
project in Xcode is refactor the project’s structure. I put the application
delegate in its own group and I create a group named, View Controllers,
for the modules of the application. For me, a module is nothing more than
a screenful of content or a reusable user interface.

View Controllers

I’m a fan of storyboards and I put the storyboards of the project in a
separate folder. I aggressively use storyboard references to make sure I
don’t end up with one large storyboard that’s slow to load and difficult to
manage.

Storyboards

Everything related to Core Data is thrown in a separate group. This
includes the data model and the extensions for the NSManagedObject
subclasses.

Core Data

I also create a separate group for extensions, protocols, generic models,
and managers. I try to avoid having groups that are named
Miscellaneous or General. This doesn’t help me organize my projects
and it makes finding files inefficient.
A group named Resources contains the project’s resources, such as
assets, audio files, and localization files. Notice that I create subgroups to
keep everything nice and tidy.

Resources

The group named UIKit contains subclasses of UIKit components.
Everything has its place in my projects.

UIKit Subclasses

This project also uses the Model-View-ViewModel pattern and I have a
separate group for generic view models, view models that are used
throughout the project. The project also makes heavy use of operations.
The Operation subclasses are located in a group named Operations.
The target’s Info.plist file is located in a group named Supporting Files.

View Controllers
The View Controllers group is split up into several subgroups, one for
each module of the application. This split is almost always specific to the
project. Use your common sense and see what works best for your
project.
Every module contains subgroups for the view controllers of that module
and such a subgroup usually contains several subgroups, such as
protocols, view models, table view cells, and collection view cells. This is
very often specific to the project.

Test Target
The test target is organized a bit differently for obvious reasons. A group
named Supporting Files contains the target’s Info.plist. I create
separate groups for the test cases, the extensions I use only in the unit
tests, and I also create a group for stubs.

UIKit Subclasses

It frequently happens that I create mock and other helper types. These
are also lumped together in separate groups, Mocks and Helpers
respectively.

On Disk
Prior to Xcode 9, a group in Xcode’s Project Navigator didn’t correspond
with a folder on disk. This has finally changed. In Xcode 9, a group by
default corresponds to a folder on disk. This means that the project
structure you create in Xcode more or less corresponds to a folder
structure on disk.
If you’re using an earlier version of Xcode, I strongly recommend that you
manually create a folder for every group you create in Xcode’s Project
Navigator. This is tedious, but it’s well worth the investment. And it isn’t
difficult.
You create a group in the Project Navigator and copy the name of the
group. Open the File Inspector on the right, click the folder icon in the
Location section, and create a new folder with the same name as the
group in the Finder window that appears. Choose the newly created
folder and click Choose to link the group to the folder. Any files or other
groups that you add to the group in Xcode are automatically added to the
folder that’s linked to the group.

What Do I Gain
Sticking to a project structure makes it easier to find what I’m looking for,
but it also allows me to focus on what matters, that is, the code that I
write. Focus is a topic I mention a lot in this book because it’s essential if

you want to get meaningful work done. An organized project that sticks to
a structure that makes sense is one less distraction to worry about.

Tools
There are several tools and scripts that help you with organizing your
projects. The best known tool is liftoff, created by the folks at thoughtbot.
It’s a command line tool that allows developers to quickly create a new
Xcode project that sticks to a predefined project structure.
This can be useful if you’re working in a team and every project needs to,
and should, use the same project structure.

Caveats
This project structure works for many projects, but there are a few
caveats. What happens if your project manager or the designer
introduces major changes? In such a situation, you need to make
changes to the structure of your project. That’s the downside. The
question is whether this is necessary and warranted. Shouldn’t the
developer start developing once the design and feature set is agreed on?

3 Project Hygiene
In the previous chapter, I wrote about structuring the projects you work
on. This applies to every software project. What I didn’t discuss in the
previous chapter is project hygiene. What should be kept under source
control? What do you do with old files and assets?

Projects Evolve
As a project grows and ages, more stuff makes its way into the
repository. That isn’t a problem because it’s inevitable. Fortunately, the
project is under source control. You’re using source control. Right?
Whenever I inherit an existing project, I start by exploring the project’s
repository and its history. You’d be surprised by what I sometimes
discover in projects. Two things that stand out, though, obsolete files and
files that shouldn’t be kept in a repository.

Obsolete Files
From the moment you no longer need or use a file, delete it. It’s that
simple. Some developers are reluctant to delete stuff and clean up a
project. They usually have a clear motivation. It’s either laziness or the
fear that they might need it later. Some day.
Good programmers are lazy, but this isn’t the type of laziness that the
adage is referring to. This is sloppiness that you should avoid. If you’re a
team lead, make sure you avoid this type of behavior in your team.
Project hygiene is just as important as taking your car to the shop every
so often.
The fear some developers have when they need to delete a file is
unwarranted if you’re embracing source control. The idea underlying
source control is exactly why you don’t need to be afraid to experiment or
delete stuff. Trust your version control system, make sure you have

backups of your repository, and hit the delete button when something’s
no longer needed.

Comments
The same applies to comments. Comments are great. I love comments, a
bit too much according to some people. But comments shouldn’t be used
to comment something out, commit it, and save it for later. If a chunk of
code is no longer used, then delete it. Should you need it later, then
source control is there for you.
Whenever I see a piece of code commented out, a warning bell goes off
in my head. Clean it up and commit it to the repository. Seriously.
Embrace source control and learn to trust it.

Documentation
Keeping documentation up to date can be challenging. I’m not aware of a
infallible solution to this problem. That said, make sure you regularly
update the documentation of your projects. Take a look at the
documentation and make sure recent changes are reflected in the
documentation.
Did you switch from CocoaPods to Carthage? That means you probably
need to update the project’s README. Is there still a Podfile at the
project’s root? And what about the Pods project? Obsolete configuration
files are more common than you think. Did someone experiment with a
command line tool that generated a configuration file and didn’t bother to
removing it when they no longer needed it? It happens.
The best strategy that I know of to keep documentation up to date is
surprisingly simple. It works best if it’s made explicit by turning it into a
policy or guideline. Whenever you make a change that contradicts the
documentation, it’s your task to update the documentation. If it’s possible,
update the documentation in the same commit that includes the code
changes.
It’s a healthy strategy for several reasons. First, it places the
responsibility with the developer that made the change. That person is in

the best position to update the documentation. Second, it minimizes the
risk that you forget to update the documentation.

Don’t Commit Everything
Keeping a project’s .gitignore file up to date is essential if you want to
avoid cluttering your project’s repository. Files that are generated are
generally ignored, such as builds and documentation. That’s also why I
prefer to leave the Pods directory out of the repository. The project’s
Podfile.lock and Cartfile.lock define the project’s dependencies, which
s sufficient to install the dependencies and build the project.
Anything that’s related to the developer or the IDE you’re using should be
ignored. Xcode keeps your preferences in the project folder and
AppCode also stores a bunch of preferences at the project’s root. That’s
fine, but you don’t need to commit those to the project. One of the
reasons is that you don’t want to have conflicts with other team members.
Sensitive information should almost always be ignored. I once worked on
a project that contained private keys. This isn’t something I recommend.
Private keys should be stored in a secure location, not in the repository.

Guidelines and Exceptions
This chapter merely describes a set of guidelines. At some point, you will
run into an exception. You need to discuss this with your team and what
you decide may differ from project to project.
As I mentioned elsewhere in this book, be critical. It’s not because Bart
Jacobs said that you shouldn’t keep the Pods directory under source
control that that is what you should do. There are plenty of developers
who disagree with this stance.

4 Document Everything
Like testing, documentation is often considered a luxury or “Something
we can do later.” This is a common misconception and, especially in
teams, it comes back to bite you.
There are various types of documentation. The one you’re probably most
familiar with is the documentation or comments in the projects you work
on. While it’s true that adding too many comments isn’t a good idea, I
hope you agree that no comments is worse.

Start With the Basics
As a basic rule, every project should have a README at the root of the
project, regardless of the project. Even if you’re creating a tiny library that
adds rounded corners to a button, then you should add a README.
Every time I come across a project on GitHub that doesn’t have a
properly formatted README that says a few things about the project I’m
looking at, I close the browser tab and move on.
You don’t need to spend days writing documentation. The basics are fine
to get your feet wet. Start with a brief description of the project, its
authors, its dependencies, and how someone unfamiliar with the project
can quickly get up to speed. The latter is often overlooked. It happens all
too often that I need to figure out which tools to install, which version of
Ruby I need to have, and on and on only to compile the project. That
shouldn’t be necessary and it can be avoided with minimal effort.
Project ownership, a topic I discuss elsewhere in the book, is often
undervalued or ignored. The project owner is in charge of creating a step
by step guide to help new developers get up to speed as quickly as
possible. If you own the project, then it’s your responsibility to make sure
such a guide exists and that it’s up to date. Did a new team member run
into an issue? No problem. Debug the problem and update the README
to make sure this doesn’t happen in the future. That’s not unreasonable.
Is it?

Make It Easy
Documentation is only useful if people use it. If you hide the style guide of
your team in a hard to find folder structure that’s shared on Google Drive
or Bitbucket, then the chances are that nobody’s going to make an effort
to look for it, let alone use it. It doesn’t matter what solution you use, as
long as you make sure your team can access it with a few clicks or key
strokes.
There are several open source solutions that make it easy to
automatically generate documentation for libraries or projects. This
means that the documentation is automatically updated when you push a
commit. Looking into an automated solution may be well worth your time.
You can even integrate your documentation with documentation browsers
or make them available online. CocoaDocs is a nice example of this
strategy. I believe it’s no longer maintained, but the tools that power
CocoaDocs are open source and available for you to use.

What to Document
The short answer is simple. Everything. The reason I recommend to
document everything is simple. It’s always a pain to figure something out
and most of the time you don’t have the time to mess around.
I remember that, years and years ago, I created a step by step guide to
set up a LAMP stack on macOS. This changed with every release, and
every time I installed a fresh copy of macOS or purchased a new
computer, I had to figure out how to set up a LAMP stack. Having this
step by step guide was a life saver. Every. Single. Time.

Up to Date
Keeping documentation up to date is challenging, especially if you work
in an environment that evolves quickly. However, more frustrating than
not having documentation is having incorrect documentation. I can’t tell
you how often I hit a wall because of incorrect or outdated
documentation. You know it should work because it’s documented. But it
isn’t working.

Keeping documentation up to date requires two elements. The first is the
most important one, a mindset and commitment to do so. Again,
ownership is key. Every page of documentation should have an owner.
That person is responsible for keeping the documentation up to date.
Avoid that one person is responsible for everything. This doesn’t work.
The second element is having a robust system. This ties in neatly with
discoverability. I’ve encountered situations in which an API was
documented in several places. The date was my only indication which
document was most up to date. That’s what I assumed.
Some people swear by tools like JIRA and Confluence. That’s fine and
I’m not going to recommend a tool. I’ve never liked these tools.
Confluence and me have never been best friends. Use a tool that you or
your team enjoy using. It shouldn’t take ten clicks and five browser
windows to add a new entry to the documentation.

Make It a Core Tool
Documentation is often an afterthought. “Oh. We still need a system to
manage the documentation. Confluence? Sure. Google Docs. That
should work.”
Don’t make this mistake. Invest in a system, free or paid, that works for
you and your team. If you find a free solution that works for you, then
that’s fantastic. If it’s a paid solution, then that’s fine too. As long as your
team uses it on a daily basis, you’re set and ahead of the curve.

I’m a Team of One
What do you do if you are a team of one? You’re a freelancer or you run
a small product business. The same rules apply. It simply means that you
need to take care of everything yourself. The rules are simpler. You’re the
owner, which means that you’re in charge of keeping everything up to
date.
Don’t make the mistake that you’ll remember how to set up Jenkins six
months from now. You won’t. Write it down and document it. You’ll be
glad you did six months from now.

Some people go the extra mile and write a blog post. They document
their frustrations by providing a step-by-step guide to, for example, set up
a build server. Thousands of people will thank you for it.

Make It a Habit
If you’re a team leader or a manager, then make sure your team makes
documenting a habit. This can be challenging, but it’s necessary. Every
developer should learn that not every aspect of software development is
fun or enjoyable.
A developer who makes documenting a habit understands what software
development is about. It’s more than writing code and making beautiful
user interfaces. Software development is creating something that lasts. It
should work today and a year from now. Documentation is a tiny gear in
the machine that makes that possible.

Time Is Money
I can see why people sometimes see documenting as a waste of time
since it has not measurable return on investment. Is that true? Are these
the same people that claim that testing is a misuse of time?
Isn’t it also true that no company measures how much time is lost figuring
out things that should have been documented? Think about that and then
consider the return on investment of proper documentation.

PART 4: WORKFLOW

1 Testing
Developers often feel guilty when I start talking about testing. They
sheepishly turn their head or mumble that they’ve been planning to write
tests but haven’t found the time. You shouldn’t feel ashamed if you’ve
never written a test. That said, you should consider starting today.

Where to Start
If you’re unfamiliar with testing, then the subject feels abstract and
complex. That’s the feeling I had before I started writing unit tests. The
truth is that testing isn’t that difficult if you break it down. Like
documentation, it’s a topic many developers don’t give much
consideration.

Start Simple
The easiest tests to write are usually those that test the model layer of
your application. If you’re new to unit testing, then it’s a good idea to start
there. Don’t start with testing view controllers or Core Data models. If
you’re new to unit testing, then that will only confuse you.
Choose a tiny class or struct, create a test target, and write your first unit
test. Run the unit test and be surprised by how easy that was.

Code Coverage
While you can test a project without it, code coverage gives you an idea
of how well your project is covered by your test suite. There are various
tools and techniques for calculating code coverage. Apple added native
support for code coverage in Xcode 7.
To enable code coverage, you check a checkbox in the configuration of
your scheme and run the test suite. Xcode automatically collects
coverage data, creates a report for you, and even displays code
coverage metrics in the source editor.

Code coverage is merely an estimate. The implementation of Xcode, for
example, inspects the code paths that are triggered when the test suite is
run. Because Xcode spins up an instance of your application when it runs
the project’s test suite, code paths that are not unit tested are also
triggered. Some of the application life cycle events in the application
delegate, for example, are triggered when your test suite is run. I believe
that Xcode takes these into account when calculating the project’s code
coverage. You can verify this in the test report Xcode generates for you.

Revealing Weaknesses
There’s a more important reason why I was excited when Apple added
support for code coverage to its IDE. Code coverage reveals weak spots
in the unit tests that I write. Xcode shows you which code paths are
triggered when the test suite is run. Green means that a code path is
triggered by the test suite and red means a code path isn’t triggered by
the test suite. In other words, red means that I need to write more unit
tests.
This occasionally happens when edge cases are in play. We have the
tendency to test the happy paths and overlook or ignore the edge cases.
What happens if the backend returns an empty result or the format of the
file you’re loading isn’t what the application expects?

Writing Better Code
Even though writing unit tests isn’t my favorite aspect of software
development, over the years, I’ve come to enjoy and appreciate it. Not
only is a robust test suite invaluable for any software project, it also
makes you a better programmer. Why is that?
When you write a test for a function or method, you’re forced to think
about the implementation of that function or method. You approach the
implementation from a different perspective.

Break It Down
Lengthy methods and massive view controllers are almost always
symptoms of code smell, subtly telling you that it’s time for a round of

refactoring. An important benefit of writing tests is that it pushes you to
keep methods short and focused.
As a general rule, a method should focus on one thing and one thing
only. If you adopt that strategy, methods no longer span dozens or,
heaven forbid, hundreds of lines. Massive methods are very hard to test.
Not only is it difficult to understand what you’re testing, too many
variables are in play, each affecting the implementation and the
corresponding tests. The number of code paths you need to test
becomes unwieldy and the result is often that no unit tests are written or
the method isn’t properly covered by unit tests.

Keep It Simple
It’s better to have a handful of short and focused methods than one
monstrous one. Why is that? The most obvious benefit is that concise
methods are easier to understand. It’s easier to wrap your head around
the method’s implementation. You have a better understanding of what’s
going on and what the possible outcomes are.
Another important benefit is the naming of methods. If you create a
method that spans dozens of lines and is responsible for half a dozen
tasks, then what are you going to name that method? If you break that
method down into smaller methods, each with a particular focus or task,
naming these methods will be easy and straightforward.
By keeping it simple, you gain clarity. By creating massive methods or
classes, you create chaos and lose focus.

Dependency Injection
From the moment I became serious about unit testing, I lost my fondness
for singletons and came to like dependency injection. It felt as if I
graduated as a programmer and no longer needed the singleton pattern
to glue the pieces of a project together.
Dependency injection is a wonderful concept that’s often ignored or
discarded in favor of the singleton pattern. Even though I don’t dislike

singletons, I always ask myself whether there’s a better solution to solve
the problem that doesn’t involve a singleton. Hint. There often is.
Dependency injection, mocking, and testing is a powerful and flexible
combination. Mocking and stubbing also become much easier with
dependency injection.

Xcode and Testing
Xcode’s support for testing has gradually improved over time. With its
support for code coverage, you now get a nice test report and the source
editor shows you if a particular code path was triggered by the project’s
test suite.

Code Coverage in Xcode

As I mentioned earlier, code coverage isn’t magical and it has its flaws.
You shouldn’t solely rely on code coverage when writing unit tests. That

said, it makes it much easier to spot holes in your project’s test suite.

My Current Test Setup
Even though XCTest has improved over the years, I usually use a few
additional libraries for making testing easier and more powerful. For
Objective-C projects, I have come to love and rely on OCMock, a
mocking library for Objective-C. Because OCMock hooks into the
Objective-C runtime, there currently isn’t an equivalent for Swift projects.
OCMock allows you to test more aspects of your code. It’s easy to mock
objects and stub methods, enabling you to test parts of your codebase
you wouldn’t be able to test with only XCTest in your toolbox.
Another library that’s great for testing is OHHTTPStubs. As the name
implies, this library makes stubbing network requests effortlessly. With
OHHTTPStubs, you no longer have an excuse to ignore networking logic
in your project’s test suite.

What Are You Testing
Not writing unit tests doesn’t make you a bad programmer. But you
should ask yourself why you’re not writing unit tests. Most studies show
that you save time in the long run because breaking changes are easier
to find and bugs are less likely to creep into your project’s codebase. It
also gives you more confidence in the code you write.
Earlier in this chapter, I briefly touched on a topic that’s very often
overlooked by developers, especially those that are new to unit testing.
What are you testing?

Implementation Versus Specification
From a developer’s perspective, unit testing an entity means writing
unit tests for every method and property of the entity. In other words,
you’re writing unit tests to test the implementation of the entity.
What’s often overlooked or misunderstood is that unit testing falls in the
category of black-box testing. This means that you don’t care how the
entity under test does what it does. From the moment you start writing

unit tests, you need to stop being a developer and take on the mindset of
a tester.
As a tester, you’re not interested in how something works. You carefully
inspect the public interface of the entity and make sure the entity
behaves as specified. You can compare this with someone testing a car.
If the tester starts the car, she’s not interested in what happens under the
hood. The specification says that turning the key should start the car
within a predefined period of time. The tester tests the behavior and
functionality of the entity under test.

Public Only
By embracing black-box testing, unit testing becomes much easier. You
don’t care about the private methods and properties the entity
defines. As a tester, you only focus on the public interface of the entity.
By unit testing the public interface of the entity, you automatically unit test
the private interface. That’s the underlying idea.

Code Coverage Can Help
There is one caveat you need to be aware of. As a tester, you’re not
interested in the private methods and properties of the entity you’re
testing. That’s fine because that’s what black-box testing is about. But it
also means that you need to carefully craft the unit tests you write. It can
often mean that you need to write multiple unit tests for one public
method or property. Why is that?
If you want to have complete code coverage for the entity you’re unit
testing, you need to make sure every code path of the entity under test is
executed, including those of private methods and properties.
As I discussed earlier in this chapter, Xcode can help you with this. If you
enable code coverage, Xcode to collect code coverage data for you. It
visualizes code coverage for an entity in the gutter on the right of the
source editor. The number indicates how many times the unit tests
entered a particular code path. This is helpful to find out where your unit
tests fall short.

It Takes Time

When I first started unit testing Cocoa applications, I tried to reach
complete code coverage by unit testing public and private methods. In
Objective-C, this is possible with a few tricks. Unit testing private
methods and properties isn’t possible in Swift. And that may be a good
thing as I explained earlier.
From the moment you start to write unit tests for a project, you need to
step out of your role as a developer and take on the mindset of a tester.
You need to view the entity you’re unit testing as a black box that needs
to conform to a specification. It’s the specification you need to test, not
the implementation.

2 Continuous Integration
While continuous integration is especially useful for teams, I believe it
also has benefits for developers that work solo. The practices I describe
in this chapter apply to anyone developing software, large of small.

What Is It
The name continuous integration may sound daunting or scary, but it
really shouldn’t. The idea is simple. One or more developers work on a
project and push their changes to a shared repository. Whenever a push
is detected, a series of automated steps is set into motion. This usually
involves creating a build, executing a test suite, and performing a number
of quality assurance steps.
There are several benefits to using continuous integration. One of the
benefits I appreciate most is that no human interacts with the final
product after code is committed to the repository. Other benefits include
test automation, code analysis, and build optimization.

Why Is This Useful
Continuous integration is useful for most types of software development.
There are many flavors of continuous integration available. The benefits
of continuous integration are most apparent in teams with multiple
developers working on the same codebase and committing multiple times
a day.
Instead of working on a feature in isolation for days or weeks, you
frequently commit and push your changes to a shared repository. That’s
when the build server jumps into action, building your application.
The reason I want to include a chapter on continuous integration in this
book is to illustrate a common set of problems that I have seen in some
of the companies I worked for. I won’t be covering continuous integration

itself in great detail because there are many solutions available, each
with their own benefits, paid, hosted, and open source.

Long Hanging Fruit
For small, personal projects, I don’t recommend using a continuous
integration solution because it comes with a bit of overhead and cost. For
critical projects, though, continuous integration brings clear benefits to
the table. What you define as critical is up to you. For me, any project for
a third party is critical, large or small.
If you or your team are new to continuous integration, then I suggest to
start with a simple setup to take advantage of the immediate benefits
continuous integration has to offer. You may want to start with a hosted
solution if you’re new to continuous integration. There are open source
solutions, but it can take some time to set up a build server, configure it,
and integrate it with services, such as Apple’s TestFlight or Google’s
Fabric.
To get your feet wet with continuous integration, try out a hosted solution
first. If you like the benefits it brings, then consider a better solution, with
better meaning more robust, scalable, and cost-effective.
The minimum setup I recommend is surprisingly basic. It includes
automated unit tests with every push, updating of translations, and
creating a build for testing. Is that enough? Is that worth it? I believe it is.
It’s too easy to forget to run unit tests before creating a test build. Right?
It’s certainly too easy to update the project’s translations before creating
a build, production or staging. And messing with test builds is something
you want to avoid altogether.
Give it a try. Spend a few hours or a day setting up continuous integration
for a project and evaluate the benefits you and your team get from it.

Avoid Human Tinkering
In an ideal scenario, you want to make sure that no human touches the
product from the moment the last commit is pushed to the shared
repository. This may sound obvious to some people, but it certainly isn’t
what happens when things hit the fan. Manually importing translations,

tweaking build flags and settings, updating version and build numbers, …
These are steps that should be avoided at any cost. If you’re scared to
push a build to production, then you have work to do. Continuous
integration can help you with this.
Let me repeat what I wrote earlier, you need to prevent that a human
interacts with the final product after the team committed their last
changes to the repository. The last thing the developer does is pushing
their changes to the shared repository.

TestFlight
I used to use Fabric for distributing test builds to testers. Apple’s
acquisition of TestFlight has changed this for me. The reason is simple. I
only need to send one binary to Apple’s servers. The same binary is used
by Apple to create a test build and a build for the App Store. My job is
limited to selecting the build I want to deploy to the App Store. What your
testers are testing is what your customers are going to download and
use. Fantastic.
This is the goal you need to try to reach regardless of the solution you’re
using. The build that your testers are testing should be identical from a
functional perspective to the one you send to Apple. This implies that
both builds reference the same commit in the repository. TestFlight
makes this very easy. Other solutions, such as Fabric and HockeyApp,
may require you to do a bit of additional work since these solutions don’t
neatly integrate with iTunes Connect as far as I know.
Choose a continuous integration solution that integrates with TestFlight, if
you opt for TestFlight, and that’s able to send builds to iTunes Connect.
You don’t want to do this manually. Remember that choosing the correct
build or archive to upload to iTunes Connect is another manual step you
need to avoid. You don’t want to be the one that uploaded the wrong
build to iTunes Connect.

Painless Releases
You need to avoid that releases are stressful and chaotic. An automated
workflow can and should help you with this. I realize that not every
developer has the fortune to work in a company that embraces

automation and testing. Why don’t you make a start by writing a build
script that automatically updates the build number?
You can even leverage existing open source tools for that, such as
fastlane, a powerful suite of command line tools that automate common
tasks, such as building, testing, generating screenshots, and sending
builds to iTunes Connect.

Make It Robust
In the chapter on automation, I talk more about the benefits of
automation. It’s important that you make your automation robust. Make
sure it’s tested and doesn’t break several times a day. This isn’t only
frustrating to anyone involved, it also makes that people don’t put a lot of
trust into the solution. When people don’t trust a system or a solution,
they tend to avoid it. That’s something you need to prevent.
If you’re working in a company that has the resources, then it pays off to
put someone in charge of continuous integration, making sure it’s
monitored and kept in check. In a small team, it’s usually a developer
that’s in charge of automation and continuous integration. This is
unavoidable if you’re small, but it can lead to frustration and a system
that simply doesn’t work. Don’t consider automation and continuous
integration an afterthought. It can save you time and money. In
professional environments, it’s a core element of the workflow and
release cycle.

Transparency
Transparency is an important aspect of working in a team. It means that
people are allowed to make mistakes, but it also means that everyone
involved is notified when something goes wrong.

Notifications
If a build fails or unit tests don’t pass, then every person working on the
project, including the project manager, should be notified of this event. It
should always be obvious who needs to take action to fix the problem.

If the team’s workflow is sloppy and not respected by the people working
on the project, then notifications pile up and they’re ignored. This is very
similar to warnings in Xcode. From the moment you ignore one warning,
it’s very easy to ignore the second and third warning. After a while, you
no longer pay attention to warnings, which is a critical, and often painful,
mistake.

Notificationitis
As I already mentioned, carefully tweak the notifications you send and
receive. From the moment people receive too many notifications, they
start to ignore them. That’s one of the reasons I’m a big proponent of
Inbox Zero. If your inbox is empty, you’re less likely to ignore or miss
important notifications.

Learning Curve
There is a cost to every continuous integration solution. There’s a
financial cost and there’s a learning curve. You can opt for an open
source solution, such as Jenkins, but that means you’re responsible for
setting up the installation as well as its maintenance. Hosted solutions
are easier to get started with but you pay a price for them. This shouldn’t
be a problem for medium to large companies, but it can be for freelancers
or independent developers.
I can assure you, though, that the investment you make pays itself back
in the long run. The development team can focus on what they do best,
quality improves, and releases are less stressful.

3 Refactoring
Refactoring is a word I frequently use in my commit messages because
it’s something I do very often. It’s a fancy word for writing or implementing
something differently. You don’t often hear or read about refactoring.
Especially if you work in a company or organization that puts an
emphasis on output or values quantity over quality, there’s little room or
understanding for refactoring.
I have a different opinion on refactoring. Refactoring is an integral part of
my workflow and there are several reasons why that is.

Technical Debt
Whenever I implement a solution to a complex problem, the primary goal
is to get the solution to work. I need to know that the basic
implementation I’ve put into place works as expected. This
implementation is rarely the one I want to keep, though. There are
several reasons for that.
I don’t know about you, but I know myself well enough that I need several
shots at a complex problem before I come up with a solution I’m happy
with. It’s not so much a matter of liking as it is avoiding technical debt.
Refactoring is an often overlooked cure to technical debt. To be honest,
it’s not a cure, it’s a vaccine.
Your first shot at an implementation isn’t going to be your best. If you
think about it, it’s odd that other phases of a project get multiple
opportunities to come up with a solution. Designers are often given the
freedom to try out several designs. A developer is rarely given this luxury.
One of the reasons is that the client or project manager can see the
design. Your implementation is usually not put under a lot of scrutiny if it
works as expected. But, if you have a bit of experience developing
software, you know that there’s working and working. If a developer tells

me “It works.” and he shrugs his shoulders, then I know it’s time for a
code review.
Core Data is a fine example. If you’ve worked with Core Data, then you
know that getting the data model right is a crucial aspect. It’s not unusual
that a data model changes over time as the application gains features
and complexity. Those changes, however, are evolutionary. They build on
what you already have. Getting the data model wrong in a fundamental
way, however, is a pain. You don’t want to go through several lightweight
or heavyweight migrations to fix something you could have fixed from the
start.
I’m currently working on a project with a complex timer engine. It has
taken me several rounds of refactoring before I ended up with a solution
I’m happy with. Why is that? Implementing a solution to a complex
problem often feels like putting together a puzzle in the dark. It takes time
before you see the bigger picture. It takes time before you can see every
component that’s involved and the various edge cases.

Building for the Future
While refactoring is a useful tool to reduce technical debt, there are
several other benefits. Instead of tackling the problems you’re currently
facing, you can think ahead. What’s the direction the product is going in?
What problems does the product solve three or six months from now?
Can we, with minimal effort, lay the groundwork for a solution that solves
these problems?
There’s a subtle difference between premature optimization and simply
optimizing for growth or new features. Let’s take Core Data as an
example. I already mentioned that getting the data model right is very
important. You want to touch the data model as little as possible. The
cardinality of a relationship, however, is something you can be flexible
with early on. It’s possible that an account only has one user at the
moment, but is it plausible that the product supports multiple users per
account in the not so distant future? Yes?
Think ahead and define in the data model that an account can have
multiple users. And to make your current work easier, define a computed
property, user, that fetches the first user. In other words, you’re currently

working in code as if an account has one user, but the data model
already has support for multiple users.
The line between premature optimization and anticipating growth is fine,
but it really pays off to spend some time considering these decisions.
Code reviews and analysis can really help with this. Let yourself be
challenged by another team member. Listen to their arguments,
questions, and input.

The Fallacy of Sunk Cost
It’s possible that you’ve invested hours, days, or even weeks into the
implementation of a solution to a challenging problem you’re faced with.
You’ve poured hours and hours into this solution. It works, well, most of
the time. The longer you spend on the problem and implementing a
solution, the more you realize that your solution is flawed. That can be a
hard pill to swallow.
Some of us are too proud to throw their work into the trash and start
anew. Sometimes you don’t even have that luxury. It can be particularly
frustrating if you’re working for yourself and you’ve invested time and
money into a solution that you’re not happy with.
It takes courage and confidence to take responsibility and admit to
yourself that you need to come up with a new solution. Many of us are
blinded by the fallacy of sunk cost. You’ve invested time and money into
a problem and that means it needs to make its money back. The truth is
that you won’t ever get that time or money back. However, you can save
yourself time and money in the future by taking another look at the
problem, learning from your mistakes, and coming up with a better
solution.
If you think this only happens to rookie developers, then you’d be
mistaken. It’s the experienced developer that has the audacity to start
afresh with a clean slate and that knows and sees the solution won’t cut
it, for whatever reason. But, again, there’s a fine line between knowing
when the solution isn’t good enough and striving for a perfect solution
that doesn’t exist. Be honest with yourself and, as always, ask advice
from team members or fellow developers.

Starting Anew
Starting with a clean slate is almost always a hard sell if the client makes
the decisions. Unfortunately, I’ve worked on projects that would have cost
less if the client had had the courage to start anew. That’s the fallacy of
sunk cost. Truth be told, it’s difficult to predict the future and it’s easy to
write this in hindsight.
While refactoring is an integral aspect of software development, you
sometimes need to have the audacity to start from scratch. Learn from
the mistakes that were made and create something that is ready for the
future. While it’s rare that you’re given this opportunity, you can erase
months or years of technical debt that slow the product’s evolution down
by starting from square one. That’s a very tempting offer for a developer.
Is it not?

4 Source Control
The day I discovered source control was one of those aha moments. I’m
a self-taught programmer and that was clearly visible in the early days of
my career. I’m sure you can guess what type of source control strategy I
used before I found out about Git. Let me give you a hint. It involved
copying folders. Ignorance is bliss, but not if you’re a developer.
Whenever I’m hooked by a new tool or technique, I try to learn everything
there is to know about it. Git was no different. In this chapter, I show you
what you absolutely need to know about source control, the basics. I take
it one step further by introducing you to the workflow that I’ve been using
for the past few years, a workflow that’s been working very well for me.

The Basics
The most popular source control solution in the Cocoa and Swift
communities is Git. That doesn’t mean it’s the best solution, but it’s the
one I have the most experience with. I love it. If you’re new to source
control, then I urge you to put down the book and learn more about Git.
Seriously. Put the book down. I’ll be here when you come back. The folks
at Fournova have a bunch of great resources to learn the basics.
It’s nice to see that Xcode has improved support for Git over the years.
Xcode 9 takes it up a notch and it sure looks promising. I use a
combination of the command line and a dedicated Git client, Tower.

Don’t Break These Rules
Elsewhere in the book, I write that once you know the rules and what
they stand for, it’s fine to break them. That rule does not apply to source
control. There are a few simple rules I stick to religiously. Let me give you
an overview.

Master and Develop

A project should always have a minimum of two branches, master and
develop. When you create a new Git repository, you get master for free.
Do yourself a favor, create a develop branch, and check it out before you
start development.

Master Is the Truth
Deployments to production always happen from master. There should be
no exceptions to this rule. Plain and simple.

Develop on Develop
Development should always happen on develop or a feature branch that
branches off of develop. There’s one exception to this rule, hotfixes.
Whenever you need to fix an urgent problem in production, you create a
hotfix branch that branches off of master. You implement the solution on
the hotfix branch and merge the changes back to master, ready to be
deployed.
Technically speaking, you don’t develop on a hotfix branch. You only fix
the problem at hand.

Commits
Commits and commit messages are your window into the project’s
history. This means that it’s important to carefully craft your commits and
commit messages. That’s one of the reasons I use a Git client because it
allows me to pick and choose which code changes make it into the next
commit. You can do the same from the command line, but it’s less
convenient. How you interact with Git is a personal choice.
There are several methods for creating a commit message. It doesn’t
matter which one you choose, but make sure you’re consistent and, if
you work on a team, adopt the same methodology across the team.
Avoid large commits. It’s true that this can sometimes be a problem if
you’re modifying the project file of an Xcode project. Not only is this
important for clarity and communication, but it’s also important for
practical reasons. If you want to cherry pick a commit, then you want to

make sure the commit you’re cherry picking only includes what you think
it includes. The same is true for rolling back commits.

Stashing
I’m always surprised by the number of developers that are new to the git
stash command. The concept is surprisingly simple. Imagine that you’re
working on a new feature on a feature branch. Your project manager taps
you on the shoulder and asks you to hotfix a problem on master. Your
workspace is littered with changes. What do you do? Do you commit
what you’re working on just to make sure you don’t lose your work? No.
Don’t do that.
The git stash command stashes the changes in the working directory
and the staging area for later use, leaving you with a clean working
directory and staging area. The stashed changes are pushed onto a
stack and you can create as many stashes as you need.
To stash the changes in the working directory and the staging area, you
execute the git stash command. The changes in the working directory
and the staging area are safely stored for later use. You switch to the
release branch, create a build, return to the branch you were working on,
and apply the stash you created earlier. It’s that simple. To apply a stash,
you pop it from the stack of stashes with the git stash pop command.
If you frequently use stashes, I recommend naming the stashes you
create. This makes it easy to find stashes and apply or remove a stash
by name.

Patching
In a way, patching is similar to stashing. Both commands group a number
of changes that you can apply later. A patch combines several commits
or the changes in the working directory. The changes are stored in a file
with a .diff extension.
Patches are useful for several reasons. It’s easy to store patches to disk
or share them with other developers. You can apply patches to branches
no matter what the branching model looks like. They’re also a good
alternative to cherry picking.

As I mentioned earlier, I interact with Git using a combination of the
command line and Fournova’s Tower. Creating a patch is very easy in
Tower. Select the commits you want to include in the patch, right-click,
and choose Save Patch for X Revisions… from the contextual menu.
Patches can be used in a wide range of scenarios. Imagine you’re
working with a teammate on a big, complex feature. You’re both working
on the same branch and firing on all cylinders, committing as if your life
depended on it. You’re about to push your changes to GitHub when you
notice that your teammate already pushed her changes. It’s time to pull
and perform a nasty merge. I don’t know about you, but I don’t like these
kinds of merges.
The solution is surprisingly simple. You create a patch, include the
commits you’re ahead of the remote branch, and reset your branch to
HEAD of the remote branch. You then pull the changes of your teammate
and apply the patch you created earlier. If you’re both working on the
same branch and modifying the same files, then it’s still possible that you
still need to perform a manual merge.
Keep in mind that a reset is a potentially dangerous operation that can
lead to data loss. Always bear this in mind when using the reset
command.

Git Flow
A project with any degree of complexity needs a robust branching model.
The branching model I have come to appreciate is the one outlined by
Vincent Driessen. Vincent’s model may look daunting at first, but it’s easy
to adopt in most software projects.
The idea is simple. A project adopting Vincent’s branching model has a
master and a develop branch. We covered that earlier in this chapter. If
you decide to work on a feature, you create a feature branch that
branches off of develop. When a feature is ready to be released, the
feature branch is merged back into develop.
When the time comes to schedule a release, a release branch is created
that branches off of develop. The goal of the release branch is to prepare
the release and fix critical bugs. A release branch is never used to

implement features. After a successful release, the release branch is
merged into master, merged into develop, and merged into downstream
release branches.
Merging into develop and downstream release branches is important to
guarantee that any work done on the release branch, such as bug fixes,
is also included in feature and downstream release branches.
Earlier in this chapter, I discussed hotfix branches. If you need to push a
hotfix to production, you create a hotfix branch that branches off of
master. After releasing the hotfix, the same merge strategy is applied as
for release branches.
This branching model works really well for me and the projects I work on.
I recommend prefixing branch names with feature/, release/, and hotfix/
to avoid confusion. If you apply this naming convention, then most Git
clients automatically group every branch type in a folder.

Some Tips
I’d like to end this chapter with a few tips that I picked up over the years.

Does It Build
You should only make a commit if the project builds successfully, without
warning and errors. This isn’t always easy, especially if you’re refactoring
a section of a project.

Ignore What You Don’t Need
Make sure you use an up to date .gitignore file. Elsewhere in this book, I
share the .gitignore file I use in Cocoa projects. Regardless of which
.gitignore file you use, make sure you understand what it includes. Don’t
include one you found on the web if you don’t understand what it ignores.

Configuration
It’s important to know and understand which files to keep under source
control. A developer checking out the project should be able to build and
run the project with minimal effort. This means that you don’t need to

include the Pods directory if you’re using CocoaPods, but you need to
include the Podfile and Podfile.lock files.

Sensitive Information
Sensitive information, such as private keys, should not be kept under
source control. Make sure you don’t compromise security by dumping
everything in the project’s repository.

5 Dependencies
The number of open source projects grows every day and it’s pretty
amazing what you can build with the help of open source software. Swift,
for example, is an open source project that gained a lot of momentum the
moment it was open sourced.
But open source projects also have a downside and so does every third
party project you rely on. Do you remember Parse, the company
Facebook acquired several years ago. A few years after the acquisition,
Facebook announced it was going to shut down the company, leaving
tens of thousands of developers, companies, and projects in the cold.
The winners of this decision were freelancers and consultants. I also had
to migrate a project away from Parse.
Why am I telling you this? It’s true that open source projects and third
party solutions can significantly speed up the development of a project. In
very little time, you can create a proof of concept or a minimum viable
product. This speed comes at a cost, though. As I mentioned earlier in
this book, there are very few shortcuts in software development. Every
shortcut you encounter has another side, a risk.

Minimize Dependencies
As a freelancer, I have the opportunity to browse many codebases. Some
of them are great. Many of them aren’t. One of the most common
problems is that projects include too many dependencies. There’s
nothing wrong with having dependencies. Every modern software project
has dependencies. The problem is that they’re often used as a shortcut
or because they’re considered indispensable.
Whenever I create a project in Xcode, I start out without a dependency
manager. That used to be different, though. Several years ago, after
discovering CocoaPods, I immediately installed this Ruby gem on my
machine. Don’t get me wrong. CocoaPods and Carthage are fantastic

projects that have helped me tremendously. But that doesn’t mean that
you can’t write a proper Cocoa application without them.

What Is a Dependency
Dependencies come in many forms and shapes. The most obvious
dependencies are open source solutions you manage with a dependency
manager like Carthage, CocoaPods, or the Swift Package Manager.
Managing dependencies with a robust dependency manager is trivial. It’s
almost too easy.
Inexperienced developers make the mistake of including too many
dependencies. After a while, the project feels like a car held together with
tape and glue, ready to crash and burn at the slightest bump in the road.
It’s true that dependencies can significantly speed up the development of
a project, but, again, shortcuts come at a price.
Remember that Parse offered developers a tempting solution, a mobile
backend with support for data storage, push notifications, and more. Most
of the projects that relied on Parse were forced to pay a hefty price when
the platform was shut down.
As I mentioned earlier, dependencies come in many forms and shapes.
Swift is a dependency of every project you work on. If you’re a Swift
developer, then you have no other option. Some dependencies are
unavoidable. Xcode is probably another dependency of your projects.
That too is out of your control unless you switch to JetBrain’s AppCode.
RxSwift may also be a dependency of your project. You could roll your
own library for reactive programming. Should you? I answer that question
in a moment.
And don’t forget the hidden dependencies of a project. If your project
depends on Moya, then it automatically has a dependency on Alamofire.

Fewer Dependencies
The idea is simple. The fewer dependencies your project has the better. I
hope we can agree on that. Every time I add a dependency to a project, I
carefully analyze whether it deserves to be part of the project. What are

the alternatives? How long would it take me to implement a custom
solution? How healthy is the dependency? Is it a liability for the project?
Every audit I set up with a developer or a company starts with a session
that, among other things, analyzes the dependencies of the project. The
lead developer of the project must be able to justify why the project
depends on a particular library, platform, or technology. If the project uses
CocoaPods to manage dependencies, for example, we inspect the
contents of the project’s Podfile.
I understand that dependencies can save time and, in the short term,
money. But what happens if you need to replace a dependency that’s
used throughout the project? What if you need to switch out a vital
component of the project and replace it with an alternative?

Mapping the Liabilities of a Project
Every dependency is a liability. Plain and simple. Even the Swift
programming language is a liability. Don’t believe me? Ask the tens of
thousands of developers that adopted Swift in its early days. Migrating
projects to the latest Swift syntax was no easy task. I can assure you.
Every project has points of failure. That’s unavoidable. You, as a
developer, have the responsibility to know about the points of failures of
the projects you work on and, equally important, to minimize their
number.

Don’t Make Your Life Too Easy
I have a few rules I religiously stick to when it comes to dependencies.
Every dependency I add needs to earn its way onto the project. The first
rule I never break is simple. I directly interact with first party libraries and
frameworks. What does that mean?
Core Data is the example I usually bring up in this context. I never use a
Core Data library to interact with the framework. Core Data’s API has
improved substantially over the years and it’s easy to use and
understand. Why would you use a third party library to interact with the
framework? Is it because you don’t quite understand how the framework
works? Convenience? Laziness? Be honest with yourself.

Most of Apple’s frameworks are very well designed. The company has
decades of experience designing APIs. It’s true that some of the older
APIs aren’t pretty and a bit verbose, but don’t let that be a reason to add
another dependency to a project. Write your own lightweight wrapper if
you want convenience and elegance. I guarantee you that it’s worth the
investment.

Rolling Your Own
Projects with dozens of dependencies very often have several
dependencies for trivial tasks, such as a helper library for Auto Layout, a
Core Data library, a convenience library for animations, and on and on.
Whenever you’re about to add a dependency to a project, consider how
long it would take you to roll your own implementation. Would it be a
matter of hours or weeks? If it only requires a few hours of work, then it
may be better to roll your own. You probably don’t need every feature of
the dependency anyway. Is it feasible to create a lightweight solution that
does the job equally well?
This doesn’t mean that you always need to reinvent the wheel, but your
first reaction should not be looking for a dependency to solve an issue.
You’re a developer. Right?

Choose Wisely
I already wrote that a typical software project has many hidden
dependencies, such as the programming language and the developer
tools we use. Some of these dependencies are easily overlooked. How
do you collect crash reports or analyze user engagement? I bet you don’t
use Apple’s analytics. Do you rely on Fabric, Firebase, or Mixpanel?
These are mature platforms, but they’re dependencies too.

Becoming a Better Developer
Relying on dependencies won’t make you a better developer. In fact, you
risk becoming lazy and complacent. Have you heard that a good
developer is a lazy developer? This is not the type of laziness that’s
meant by this.

I’m a big fan of open source software. Unfortunately, the popularity of
open source software has a dark side. Projects like Alamofire and Moya
are fantastic. A committed group of developers has made it their goal to
create a beautiful piece of software for everyone else to use. Projects like
Alamofire are incredibly popular. They make your life as a developer
easier.
The downside is that many developers have come to rely on Alamofire
without learning the basics first. A surprising number of developers
doesn’t know how to use URLSession to perform a network request. Is that
a problem? I believe it is. If I were to interview a developer for a position
and he or she doesn’t know how to perform a network request, I wouldn’t
hire that developer.
Samsara is an application I have been developing for several years. It
makes a handful of network requests. In such a scenario, a networking
library like Alamofire or Moya is overkill. It’s true that NSURLConnection, the
predecessor of URLSession, had an API that wasn’t terribly elegant. The
introduction of URLSession several years ago has changed this. The API
isn’t as sophisticated as Alamofire’s or Moya’s, but it does its job well.
That should be your first choice.

Watch Out for the Defaults
There are several dependencies that have become almost default
dependencies. These include libraries and frameworks for analytics,
crash reporting, and logging. I consider it a dangerous practice to make a
dependency a default dependency. I understand that your application
needs crash reporting and analytics, but does that mean that you need to
opt for Fabric or Firebase? Did you know that Apple also has crash
reporting? You can even inspect the crash reports from within Xcode,
pointing you to the line that caused the crash.
I’m not pleading that you should avoid Fabric and Firebase, but don’t
make them default options. Every dependency needs to earn its place
onto the project. The same is true for the many SDKs that are available,
such as the Twitter and Facebook SDKs.

Challenge Yourself

I’d like to challenge you. The next time you create a Cocoa application, a
side project maybe, avoid relying on any third party dependencies. See
how far you can go without including third party libraries or frameworks.
Impossible? Think again. At its core, a developer is someone that solves
problems. This is a problem you can solve. Believe me.

6 Automation
“A good developer is a lazy developer.” It’s a phrase I use several times
in this book. I believe the term “lazy programmer” was first coined by
Philipp Lenssen. The idea is that a programmer wants to avoid being
repetitive whenever possible. But that’s not the only reason automation is
important.
Automation can also minimize human error. Continuous integration,
which we discussed earlier in this book, is an example of this. By
automating a sequence of steps, we reduce or eliminate the number of
manual steps a team needs to take to deploy a build to production.
Automation doesn’t need to be rocket science, though. The Cocoacasts
website is backed up automatically. This is a trivial example of
automation, but the result is that I have peace of mind and, when things
hit the fan, I won’t lose any data.
Let’s start with the basics of automation, scripting.

Scripting
Many of us instinctively automate tasks we need to perform frequently. If
you’re using an application launcher, such as LaunchBar or Alfred, or a
snippet manager, such as TextExpander or Dash, then you’re already
embracing automation.
With the release of Swift, however, you can take scripting to the next
level with projects like Marathon, Swiftline, and Commander. Several
frameworks, libraries, and tools have emerged that allow us to use Swift
to create scripts and automate a slew of common tasks.
Before the introduction of Swift, I used Ruby to write small scripts that
helped me automate a collection of mundane tasks. I’m slowly porting
some of those scripts to Swift. You can use from a wide range of
languages, including JavaScript, Python, and Perl.

Build Phases
Xcode build phases are ideal for automating tasks you tend to skip or
forget. For personal projects, I use Realm’s SwiftLint to make sure the
code I write is consistent and sticks to a set of guidelines. SwiftLint is
easy to set up and integrate with Xcode in a build phase. You can even
trigger SwiftLine using fastlane.

Automated Testing
It’s no secret that I’m a fan of automated testing. It isn’t hard to set up
and it builds confidence. Every commit you push to a shared repository
triggers the test suite, immediately showing you if you’ve broken
anything. This feedback loop allows you to confidently build a robust,
stable product. Not having to think about running your tests is essential.

Documentation
If you or your team maintain a framework or library, then you need to
make sure its documentation is up to date. As I mentioned elsewhere in
the book, it’s frustrating to work with outdated or incorrect documentation.
The good news is that this is another task that can be automated. If you
properly document the code you write, tools like Realm’s Jazzy can
automatically generate documentation for you. Make it accessible to your
team and you have access to up to date documentation with every
commit you push to the library’s or framework’s repository.

Continuous Integration
Earlier in this book, I wrote about continuous integration and its benefits.
It’s a more sophisticated form of automation that can help you and your
team stay on top of larger, complex projects with many moving parts.
Remember that one of the goals of automation is reducing the number of
manual steps you need to take to deploy your product to production.
From the moment a developer pushes the last commit to the shared
repository, no human should tinker with the build that’s deployed.
If you work at an agency or a development shop that manages dozens of
products, then having a robust continuous integration solution isn’t a

luxury. It’s essential. No two projects are the same and every project has
its own requirements, dependencies, and configuration. You don’t want to
remember those and you don’t want to manually tweak build settings
moments before you trigger a production build. Take your work and that
of your clients serious and invest in a continuous integration solution.

fastlane
A few years ago, Felix Krause started developing a suite of tools for
automating common tasks related to Cocoa development. This suite of
tools is fastlane. At the time of writing, fastlane is a part of Fabric and
Google acquired Fabric not too long ago.
The tools are open source and under active development. Felix is still
very much involved in this amazing suite of command line tools and I
recommend that you take a look at fastlane if it’s new to you. My
workflow doesn’t rely on fastlane, but I do use it for generating
screenshots, building, testing, and pushing builds to iTunes Connect.
Felix’ suite of tools is an essential component in many companies
because it also solves common problems developers face, such as
creating and renewing provisioning profiles, creating code signing
identities, and keeping them synchronized through Git. It’s an amazing
collection of tools.

Keep It Simple
Automation is great, but it needs to work reliably. For example, if your
continuous integration setup isn’t reliable, your team will start to lose
confidence in it and more time is spent working on getting it to run than
benefitting from it.

7 Privacy
Privacy and security are hot topics and rightfully so. What developers
often don’t realize is their role in protecting the user’s privacy. In the
chapter about security, I already wrote about privacy and what you can
do to make sure the data of your users is kept from the prying hands of
people and companies with questionable ethics.
Many parties are interested in the data of your users, for various reasons.
From a developer’s perspective, it’s less important who’s after this
information. What’s important is that the users of your application trust
you with their information and they expect you to keep it private and
secure.

Protecting the User’s Privacy
Even though privacy isn’t a fancy topic and it isn’t top of mind for most
developers, I hope you’re at least keeping privacy in mind when you’re
building software. You sometimes have no other option, for example, if
you’re developing an application for a bank. But there is a range of less
obvious application types that privacy is important for, for example,
applications that have a link to the user’s health.

Who Do You Work With
I already wrote about dependencies and how important it is to properly
vet any dependency of a software project. This also impacts privacy. As I
wrote earlier in this book, third party services, such as analytics and
advertising, usually offer their services for free. Why is that?
You’ve probably heard the phrase “If you’re not paying for the product,
then you are the product.” Some companies collect and sell information.
They collect user information, such as browsing behavior and location
data, and sell it to advertisers. While the services they offer are free,
there’s a catch.

It’s not always easy to discover which companies are legit and which
ones to avoid, but if you, the developer, include a third party’s service in
your application, then it’s your responsibility to make sure it doesn’t
violate the user’s privacy. You’re on the hook if something happens with
the user’s data.
You can remedy this by publishing a privacy policy for your application in
which you explain what happens, or doesn’t happen, with the user’s
information. This also means that you need to know how the third parties
you work with use your application to collect information. This can be
tedious. It’s ironic that it’s usually easier to include a third party SDK than
to find out how the third party uses your application for their own gain.
As I mentioned earlier, I no longer include third party services, such as
analytics and advertising in the projects I work on. That’s a conscious
decision and I have the luxury to do this. Unfortunately, this isn’t possible
for everyone. In fact, it may be rare.

Giving the User Control
One of the reasons for choosing for Apple’s ecosystem, both as a
consumer and as a developer, are the values the company holds. Privacy
is important to Apple and there are very few companies that follow its
example in the technology industry.
App Review is a fine example. While App Review has received a fair
amount of flak over the years and is often seen as an obstacle for
developers, I applaud Apple for putting this barrier in place. After more
than nine years, the company sticks with its ambition to keep the App
Store safe and healthy.
Whenever I install an application from Apple’s App Store, I know that I
won’t be installing a piece of malware that sends the contents of my
address book to a remote server. App Review isn’t perfect or bulletproof,
but it’s demonstrated that it does a pretty good job at protecting you and
me from people and companies with dubious practices.
You need to give an application your explicit permission for it to access
your address book, photos, and location. This is a good thing because it
puts you, the user, in charge of managing your privacy. While this

solution isn’t perfect, it at least gives you the opportunity to be conscious
of your privacy if that’s what you want. Some people don’t care about
their privacy and that’s fine. The user is in charge.

Third Party SDKs
While you can’t always choose which companies you work with, you, the
developer, are responsible for the user’s data, how it’s used, and who
can access it. Over the years, many scandals have surfaced of
companies that used devious tactics to get a hold of the user’s personal
information, such as their contacts and location.
If you include a third party SDK in your application, then you should
realize that you have no idea how the company providing the SDK is
using your application’s data. This is something we often forget.
This is closely tied to the discussion about dependencies earlier in this
book. Not only is a third party SDK a dependency that can cause havoc
in your application, it also has unlimited access to your application’s data.

Choose Wisely
Consider the companies you implicitly, or explicitly, work with. I don’t want
to imply that you shouldn’t trust Apple, Google, and Facebook, but you
need to be mindful of the services your application and your business
uses.

8 What to Do When You Inherit a Software
Project
As an employee, freelancer, or consultant, you inevitably end up with a
foreign codebase on your plate at some point in your career. In a way,
inheriting a software project is much like receiving the keys to a house or
car you don’t know anything about. You hold your breath, afraid for what’s
about to come. But you’re also a little excited, curious to find out what
you’ll be working on for the next weeks, months, or longer.
A new project can be overwhelming. Depending on its size and state,
opening a project for the first time can be downright shocking. Don’t let
this intimidate you, though. Some things are hard, but that doesn’t mean
they’re impossible.

First Things First
Take your time to explore the codebase and learn more about the project
as you go. The first few days can be disorienting and it may feel as if
you’re not making any progress. And that’s fine.

Talk to the Previous Owner
If the previous owner of the project is still around and able to do a formal
handover, then you’re in luck. This is a major advantage. Prepare a list of
questions and fire away during the handover. Don’t be shy. You’re new to
the project, which means there are no silly or dumb questions.
Is the previous owner not around, then try to get a hold of someone who
worked on or is familiar with the project. That’s the next best thing.

Source Control
Whenever a project is thrown in my lap, the first thing I do is clone the
repository. Is the project not under source control or, even worse,
someone tampered with the repository’s history, then that’s the first red

flag. It’s possible the previous owners are trying to hide something. In
that case, your first task is to create a repository for the project. If things
go haywire, it’s easy to retrace your steps.
If you’re in luck and the project’s under source control, then take a close
look at the commit history. For now, the most important questions are
“Who made the first commit and when was it made?” and “Who made the
last commit and when was it made?”
The time of the first and last commits tell you a lot about the state of the
project. You may even be able to contact some of the people that worked
on the project. Source control is invaluable for any software project.

Compatibility
Depending on the software project, you need to make sure your
development environment is compatible with the project’s technology
stack. A Cocoa application, for example, requires a machine running
macOS with a copy of Xcode installed.
It may even be necessary that you need a specific version of macOS or
Xcode to bring the project to life. As I mentioned earlier, if you can talk to
someone that used to work on the project, then you’re saving yourself a
lot of time and frustration.

Build and Run
The moment of truth arrives when you compile the project for the very
first time. Give it a try. Build and run the application on a device or in the
simulator. This step is critical because it reveals some of the project’s
dependencies, such as third party frameworks and libraries, and it can
also expose some early problems.
If the project uses a dependency manager, such as CocoaPods or
Carthage, then you may need to install the dependencies first before
you’re able to compile the project.
Once you’ve successfully built and run the project, you’ve reached your
first important milestone. You can now start to explore the project and
collect information.

Collect Data
With the project up and running on your development machine, it’s time
to get to know your new best friend. It’s important to understand how the
project works and, more importantly at this stage, find out what its
requirements are.
For a Cocoa application, for example, the deployment target is an
important piece of information. It tells you what APIs you can use and
which devices the application is compatible with. Are you dealing with a
universal application or does it only support iPhone and iPod Touch? Has
the project been updated for retina displays? Do you think that’s a silly
question? Think again.
Some projects have been collecting dust for years. This can sometimes
mean that you need to make significant changes before you can submit a
build to Apple’s App Store. As of June 2015, for example, Apple requires
new applications and updates to existing applications to include 64-bit
support. If the project depends on a third party framework or library that
hasn’t been updated in years, this may be a problem.

Dependencies
Speaking of dependencies, you’re probably starting to get a pretty good
picture of the project’s dependencies. It’s time to take a closer look. Are
the dependencies managed by a dependency manager or are they
included in the main project?
With a bit of luck, the previous owner used a dependency manager to
separate the dependencies from the main project. In that case, it’s
straightforward to verify the current version of each dependency and, at a
later stage, update them.
In some cases, dependencies are included in submodules or, if you are
less fortunate, they’re mixed in with the project. The latter makes
updating dependencies a pain. Migrating third party dependencies
outside the main project with the help of a dependency manager is a
worthwhile investment. It’ll save you many hours and headaches.

Working on the Project

How you approach a project largely depends on the time you’re allowed
to spend working on it. If you only need to step in to fix a handful of bugs,
then it isn’t worth spending days or weeks familiarizing yourself with the
codebase.
Are you tasked to implement a major feature, then it’s key that you know
how the application is architected and how it operates. If you’re the new
owner of the project and in charge of maintaining the project for the
foreseeable future, then you have the luxury of investing time and energy
to clean up the codebase, refactoring neglected parts, and making the
project yours.

Document Everything
No matter what project you work on, it’s important to document as much
as possible. The README of the project is a good starting point. For
larger, more complex projects, it can also be useful to document features
or include an overview of the application’s core architecture. It helps
other developers become familiar with the project and it also benefits
you, the maintainer, in the long run.
By commenting your code, documenting the project, writing sensible
commit messages, and maintaining a list of bug reports, you have most
of the tools you need to stay on top of your project.

And Beyond
What’s next? That’s a good question. In this chapter, we only scratched
the surface. Starting work on a foreign or legacy software project can be
messy. It may push you out of your comfort zone, but that’s a good thing.
Leaving your comfort zone from time to time keeps you sharp, forces you
to be creative, and prevents you from becoming complacent.

9 Speed, Quality, and Technical Debt
The first version of a product can never be released soon enough. That
makes sense. As long as designers and developers are working on a
product that isn’t making money, it’s costing money.
But speed can come at a cost. To gain speed, you need to make
sacrifices. And very often speed is traded for quality, resulting in technical
debt.

Speed and Quality
In product development, speed and quality are almost always
irreconcilable. Increasing the velocity of a project means compromising
on quality. From a development perspective, this usually results in the
creation or accumulation of technical debt.
Assume for a moment that you’re the product owner of a software
project. The first version of the product needs to include five major
features. Each of these features takes a week to develop. The problem is
that the client wants to ship the first version of the product in three weeks.
What do you do?
You have several options. The most obvious one is dropping two
features. Unfortunately, that’s rarely something the client agrees to.
Another option is cutting down development time of each feature by one
or two days. This usually translates to removing anything that doesn’t
involve the implementation of the feature, such as code reviews, quality
assurance, and testing.

Technical Debt
Technical debt can creep into a project without the product owner
knowing about it. The development team usually knows, though. If the
team is led by a senior developer and code reviews are baked into the
company’s culture, technical debt is easy to spot.

A fast approaching deadline can cause even the best to ignore technical
debt. The symptoms start to appear when new features take longer to
build than expected and regressions make their way into the product.
These are the early symptoms of technical debt.
In advanced stages, technical debt takes a project hostage. Nobody
wants to touch the project anymore. Features take ages to complete and
are often compromised by technical limitations caused by technical debt.
Days, weeks, or months of bug fixing are needed to stabilize the project.
I’m not exaggerating.
In the meantime, the product itself evolves at a snail’s pace. The speedy
start that was once so important for the project’s success has long been
forgotten and, looking back, wasn’t that important after all. It rarely is.

Focus
If the client wants to ship in three weeks, the correct answer is removing
features. For projects with a long shelf life, you want to avoid technical
debt at any cost. Technical debt is very much like a virus. It’s hard to
eradicate and, if it isn’t treated in its early stages, it spreads out rapidly
across the project’s codebase.
Focus is essential to avoid technical debt. Instead of rushing out a
feature, you take the time to craft something that stands out. This doesn’t
only relate to the final product; it also involves the development aspect of
the feature.
You don’t need to overengineer the solution, but you need to make sure
the feature can grow beyond its current scope. You plan and anticipate
how it can or could evolve.

How to Get Rid of Technical Debt
There’s no miracle cure to rid a project of technical debt. You need to
take action, though, if you want to avoid worse.

Refactoring

The least radical approach is refactoring the project, focusing on one
problem at a time. If you’re in luck, one round of refactoring is sufficient.
However, most projects suffering from technical debt have many
problems that need fixing.
As I mentioned earlier, technical debt spreads like a virus and that means
many areas of the codebase are infected. I strongly advise against a
single round of refactoring. Map the problems you plan to attack and
spread the refactoring over several releases. This ensures the release
cycle isn’t blocked as long as the refactoring is ongoing.
In the meantime, make sure you don’t introduce new problems. Hold off
on new features if possible. Don’t make the same mistake twice.
If you’re working on a large project with years of history, be prepared to
spend weeks or months refactoring. That’s the price you pay for technical
debt.

Clean Slate
The most radical approach is starting anew. This means you don’t need
to spend months refactoring. This isn’t an option for every project. If you
have the opportunity to start with a clean slate, though, you’re in luck.
While it means that you need to implement every feature from scratch,
it’s an opportunity many developers would grab with both hands. Learn
from your mistakes, or those of your colleagues, and create an amazing
product.
I’ve worked on several projects that would have cost less if the project
was rebooted. But that’s often a very hard sell. The client doesn’t see the
problems the developer sees. They only start to see the symptoms of
technical debt when deadlines are missed or features become very
expensive.

Taking Shortcuts
Taking shortcuts rarely pays off in software development and most
developers know this. But deadlines are often more important and

developers rarely have the authority to make decisions about the feature
set of the product.

PART 5: TEAM

1 Code Reviews
Like unit testing, code reviews are often seen as a nice feature if there’s
some time left on a project. This misconception stems from inexperience.
Once you start scheduling regular code reviews, you start to appreciate
the value for anyone involved. If you work in a team, you’d be crazy not
to take advantage of the knowledge, experience, and input from your
colleagues.

Just Start
Code reviews don’t necessarily need to have a goal. Pick a time and date
to sit together with one of your colleagues, or as a team, and have him or
her scrutinize your code. The simplest questions are often the most
powerful ones. A common misconception is that code reviews are only
useful to debug an issue or find problems in a project.
Code reviews are first and foremost a tool to improve yourself. I’ll talk
more about that later in this chapter.

Calendar and Agenda
It’s important that a code review is focused and productive. That’s why I
always recommend to schedule code reviews in the calendars of
everyone involved and to have an agenda before the code review starts.
Every participant should be able to access and modify the agenda.
One of the participants needs to take the lead. That doesn’t mean that
only he or she can ask questions. It simply means that someone needs to
make sure the code review respects the agenda and keeps the session
productive.

Make Them Actionable
Code reviews can be very useful if they’re scheduled at regular time
intervals. If that’s an option, I recommend compiling a list of actions at the

end of each code review and evaluating the actions at the start of the
next session.
This also means that the participants of the code reviews need to keep
each other accountable. If you commit yourself to refactoring a
problematic view controller in a project, then you need to make sure it
gets done by the next code review. If you ignore accountability, you risk
turning the code reviews into a required meeting nobody enjoys or takes
anything away from.
The goal of a code review isn’t finding bugs. The benefits are much
broader. You critically inspect someone’s code and discuss it with an
open mind. The goal is to learn and to improve the quality of the code.
Finding and fixing bugs is a welcome side effect.

Keep Them Small
When a senior developer sits down with a junior developer, the mistake
that’s often made is biting off too much at a time. If the junior developer
made dozens of commits since the last code review, adding hundreds or
thousands of lines of code, then the code review is going to feel
overwhelming. You need focus and direction.
Keep a code review small and focused, especially if you’re training
someone. The goal isn’t to cover as much ground or code as possible.
The goal is to go through a chunk of code, ask questions, and brainstorm
ideas and alternative solutions. Even senior developers can learn from
developers with much less experience.

Be Prepared
I already mentioned that an agenda is indispensable for productive code
reviews. It takes more to be prepared for a code review, though. Are you
unfamiliar with the project? Make sure you take some time to dive into
the codebase to ensure you know what the project entails and how it’s
organized. Ask a colleague for help if you have little time.
If you have no idea how the code you’re reviewing fits into the project,
then you might as well review a random block of code you found on the
web. This doesn’t mean that you need to spend hours browsing the

codebase. Familiarize yourself with the project and zoom in on the code
you’re planning to review. That’s a good start if you’re short on time.

Tools
There are many, many tools available for organizing and structuring code
reviews. I’m not going to mention any of these tools because I feel that
they’re secondary. Most of these tools have the option to send someone
a code review. While I understand why this feature exists, the code
reviews I’m talking about in this chapter are live code reviews, two or
more people having a discussion about a particular piece of code.
You can still use a tool to keep code reviews organized and structured,
and I recommend you do, but make sure you don’t overlook the essence
of code reviews. That’s the main takeaway of this chapter.

That Hurts
Finding out during a code review that you introduced a bug can be painful
and it can hurt your ego. To be honest, this is a facet of code reviews that
I like. Why is that? Nobody likes to make mistakes and, from my
experience, developers in particular hate to be pointed out that they
made one. A fellow developer pointing out that you made a mistake can
be hard to swallow.
It’s therefore essential that code reviews are organized in such a way that
the finger isn’t pointed at someone. Everybody makes mistakes. No
exceptions. If you don’t believe me, then have a look at the crash reports
of the projects you worked on in the past month or year.
It’s a good sign if it stings a little when someone uncovers a bug you
made. It shows that you care. Don’t be arrogant and try to prove them
wrong if you know they’re right. You can only grow as a developer if
you’re willing to grow and learn from your peers. Learning from smart
developers is one of the few shortcuts to speed up your career. Take
advantage of this shortcut whenever you can.

Convincing Management

It’s often difficult to convince management of the value of code reviews.
As with testing, it doesn’t seem to result in a direct return on investment.
Even though the results aren’t directly measurable, the return on
investment comes in many forms and shapes.
The most obvious benefit is an improvement of the code quality. A less
obvious result is that developers feel more confident in the code they
ship, and that isn’t only true for junior developers. Having a second pair
of eyes look at a complex piece of code can do wonders.
If everyone enters a code review with mutual respect, it can also
strengthen the team. This is a benefit that isn’t immediately visible and
easily overlooked.

Frequency
How often should you schedule code reviews? That depends. If you
schedule code reviews only once a month, then you may overwhelm
developers with the amount of code that needs to be reviewed.
Remember that small code reviews are most effective. To reduce the
number of issues you find during a session, it’s a good idea to schedule a
code review after the code you’re reviewing is covered by automated
tests. This is a good strategy for two reasons.
First, you can inspect the code as well as the tests during the code
review. Second, trivial issues that are caught by automated tests should
already be resolved before the code review takes place.
There are several other factors you need to take into account, such as
the size of your team and the type of software you’re developing.

But It’s Just Me
What do you do if you’re a team of one? That makes it more difficult, but
there are several solutions. Even though you work alone as a freelancer
or independent developer, or just as a hobbyist, you can always ask a
fellow developer to take a look at your code. You can schedule code
reviews and explore each other’s codebase from time to time.

This can be even more powerful than having code reviews in a team.
Why is that? Each developer has its own style and this is usually even
more the case for developers that work on their own. It can be eyeopening to see someone else’s code or have someone critique your
project.
One of the services I offer is code reviews and project audits. It can be
useful to have a third party take a look at your code, ask questions,
suggest alternatives, and, from time to time, find bugs.

Give It a Try
Code reviews have many benefits. If you’re new to code reviews, then I
encourage you to give it a shot. I recommend running a trial for at least a
few weeks or months. Give your team the chance to become familiar with
the process and tweak it as you go. You won’t get it right from the start.

2 Adopt a Style Guide
Even if you’re working on your own, in a team of one, adopting a style
guide can be very helpful and useful. It ensures that you stick to a set of
guidelines you define. The result is that your code is consistent and easy
to read.

Why Have One
The most obvious benefit of having a style guide is promoting
consistency. It ensures that the code you and your team produces is
consistent. This benefit alone is enough to consider adopting a style
guide. But it’s only the tip of the iceberg.
Another immediate benefit of having a style guide is improving
readability. When I browse a foreign codebase, it usually takes some time
to become familiar with the author’s style. This includes naming
conventions, comments, spacing, and even the use of curly braces. A
style guide normalizes this, making it easier for developers of the same
team to read each other’s code.
A third subtle benefit is reducing friction within the team. There’s no
internal discussion between team members about the use of curly braces
and it ensures developers don’t need to think about their style. They
simply stick to the conventions defined in the style guide.

Automation
I’ve worked in teams with a formal style guide that wasn’t enforced in any
way. Team members were simply expected to stick to the style guide. If
you decide that a style guide can benefit your team, then I recommend
you also invest in automation to enforce the rules defined in the style
guide.
This is very easy to set up if you’re using Xcode. Adding a build phase to
the project that triggers a shell script or a command line tool should do

the trick. Be careful that the style guide you enforce locally is up to date.
If you open an old project, make sure it uses the most recent version of
the style guide.

Rough Transition
Making the transition from no style guide to a clearly defined specification
can be rough for some team members. I advice enforcing the style guide
for new projects only unless your company runs a product business.
You need to avoid that developers are spending hours or days updating
projects because of style violations. Not only is this time-consuming, it
almost always introduces bugs if there’s a large number of changes that
need to be made.
Adopting a style guide is a big change for many developers. Try to ease
the pain by gradually enforcing the style guide.

3 Working In a Team
The whole is greater than the sum of its parts. — Aristotle
Working in a team can be a joy with many benefits, but it can also be a
challenge. Every team member has a responsibility towards the team,
and this determines in a significant way how effective the team is.

Hire the Right People
Growing a company is challenging for a wide range of reasons, hiring is
one of them. Young companies are often still discovering themselves,
and it may not always be clear who you want to hire. You know what their
resume should look like, but how do you know whether they fit the
company?
If you aim to build a reliable, efficient team, you need to hire people that
excel in a team. You need people that are ambitious and eager to work in
a team. Those qualities don’t always go together, though.
What’s most important is that the person you hire fits the company
culture. Finding someone that ticks every box is hard, and it takes time,
especially in the technology industry.

Leadership
A team needs a leader, even small ones. One person needs to make
decisions and have the last word when push comes to shove. A leader
often has a significant impact on the team and the team’s ethos.
Having a healthy mix of junior and more senior developers is a good
strategy. Attracting someone who has experience working in and building
a team is a big plus.

Communication

Elsewhere in the book, I write about focus and productivity. At times, it’s
necessary to put on your headphones and focus. That’s unavoidable if
you want to get work done.
What I’ve also noticed is that this culture of headphones can sometimes
result in a lack of communication. Talking to your teammates is as
important as getting work done, especially if you’re working towards the
same goal.
You can solve this seeming conflict by organizing team meetings that
focus on team building. Take the afternoon off for a team event that
doesn’t have anything to do with work. Or organize a weekly lunch to talk
about a technical topic. Start a discussion and leave room for everyone to
share their opinions.

Give It Time
It takes time to turn a group of people into a team. It isn’t necessarily a
natural process and don’t expect it to be. A solid team isn’t built overnight
nor does it happen by accident.
A good team strengthens when it gets tough. When something goes
wrong, there’s usually one person to blame, but you take the hit as a
team. It’s a team effort, and you need to avoid that someone is singled
out, taking the blame. You’re in this together. People should be allowed to
make mistakes.

Respect
Not everyone is cut out to work in a team and you can’t always choose
the other members of your team, which can cause friction. That’s why
hiring is such an important aspect of a growing company and something
many struggle with. I’m sure you can think of a few examples.
Respect is a key ingredient of a healthy team or company. This may
seem obvious, but it’s not always easy. You can’t choose the people you
work with. The larger the team, the more likely it is that you’re going to
meet someone you don’t see eye to eye with. This doesn’t need to be an
issue, though, as long as you respect one another.

When Things Hit the Fan
Things will go wrong if you’re solving complex or ambitious problems.
Accept that this is inevitable. But, as I mentioned earlier, the team takes
the hit.
You obviously need to investigate the issue and find out who made a
mistake, but remember that it’s a team effort. You’re in this together.
Some team leaders or managers try to cover problems up. I recommend
taking the opposite approach. Analyze the problem and investigate, as a
team, what went wrong. It’s in the tough times that teams are built or fall
apart. That’s when you discover how much you can rely on your team
and your fellow team members.

Ownership and Responsibility
Taking ownership and responsibility are aspects of working in a team that
aren’t talked about very often. However, the most performant teams and
companies I worked with are the ones that embrace these values.
There are dozens and dozens of small tasks in a company. Having a
committed team makes handling these tasks much easier. Knowing that
someone takes care of a particular task you don’t need to worry about is
one of the most enjoyable aspects of working in a team.
That’s also one of the aspects I enjoyed most when I was working as a
subcontractor. While I’ve worked with many project managers over the
years, I had my favorites. An experienced project manager is core to an
effective and efficient team. They’re the glue that binds clients, designers,
developers, and testers together. An experienced project manager owns
the project and takes the final responsibility for every aspect of the
project.
And developers need to do the same. If something goes amiss, then the
person responsible for that aspect needs to step up and take care of the
problem.
When something goes haywire and people start pointing fingers at each
other, then there’s a problem that needs to be addressed. It should be

obvious who’s responsible and who needs to take action. That person
shouldn’t be blamed for what went wrong, though. It merely eliminates
the discussion who needs to step in and fix the problem.

Share and Ask
I’m sure it’s obvious that you should share what you know with the team
and learn from your teammates. It’s one of the shortcuts in software
development that you should take advantage of. Stack Overflow is great,
but nothing replaces a healthy discussion with your teammates about a
technical topic or a problem you’re trying to solve.
And don’t forget to include designers and managers. I’ve had many
interesting discussions with team members that weren’t technical.
There’s more to software development than writing code.

4 Being a Leader
As a freelancer, I don’t have much experience leading teams, but I’ve
been part of several teams as a subcontractor. Leading a team and
acting as a leader can be challenging for developers because they’re not
always asking for this type of promotion. As a company grows, teams are
formed, and a team needs a leader.

Listen and Be Open
A good leader listens to the people he or she works with. It can be
frustrating to be part of a team in which your voice isn’t heard. It doesn’t
mean that you need to take action based on what you hear, but you need
to make sure every member of the team knows that he or she can
approach you, talk to you, and know that you understand them.
It’s equally important to be open in your communication. Always make
sure that there are no unresolved issues in your team that create tension.
Talk to your team members, as a team, and in one-to-one meetings.
Everyone needs to be up to date about what’s going on in the team and
the company. If a team member or employee is unaware of an important
event or announcement, then that person may feel left out or not part of
the team.

Modesty, Humility, and Respect
The most memorable leaders I worked with are modest and humble.
They can bring the best out of you, taking advantage of the strengths of
each member of the team.
Developers that don’t feel comfortable leading a team sometimes have
the tendency to please the team they lead in an attempt to earn their
respect. If you climb the ranks in a company and are promoted from team
member to team leader, then earning that position can be challenging.
But you don’t earn the respect of your team by attempting to please
them.

Work as a Team
Most of the team or project leads I’ve worked with had too much on their
plate. That’s a very, very common problem for people leading a team or a
company. Their workload isn’t always the cause of the problem, though.
Two causes are very common.
The first cause is wanting to do everything yourself. Inexperienced
leaders, especially those with a healthy dose of pride, find it hard to ask
the members of their team for help. You won’t be able to do everything
yourself and you need to learn to delegate tasks to the members of your
team.
This can have a dramatic impact on your workload. At first, it can feel as
if you’re asking someone else to do your job, but that feeling quickly
disappears once you discover that you have more time for other tasks,
such as organizing your team and setting up one-to-one meetings with
the people of your team.
Delegating is something you need to learn and it also means you need to
know the people on your team very well. Each member has their
strengths and weaknesses. It’s up to you to leverage this diversity and
use the strengths of your team to your advantage.
The second cause is closely related to the first. Handing control over to
other people can be scary, very scary. You’re the leader of your team and
that means that you carry the final responsibility. As a result,
inexperienced leaders have the urge to make sure everything is exactly
as they want it to be, as if they did it themselves.
This approach isn’t healthy. First, the result is that you increase your
workload for no good reason. Second, you may give other team
members a feeling of inadequacy, not being good enough. It can
sometimes be good to let things hit the fan. Everyone learns from such
an experience.
If you still struggle with this, then you may want to embrace code reviews
or roundtables. These can be very effective strategies to build your team,
show them how things should be done, and make sure everyone is on
the same page.

Working With People
As a developer, you’re used to finding and implementing solutions to
problems. It’s not that straightforward if you’re working with people.
Developers share a passion for solving problems, but they’re human
beings and each of us is different. This means that you need to approach
every member of your team or company a little differently.
This can be one of the most challenging aspects of being a leader
because it means you need to rely on your intuition. You need to be able
to read the people on your team and rely on your people skills.
Some of your teammates are extroverts and you always know what’s on
their mind. Others are quiet, shy, or not eager to share their opinions with
others. It takes leadership to ensure the voice of the quiet is also heard
by the extrovert.

Follow Your Gut
Even if you sign up for a crash course in leadership, it takes time for most
people to become a leader and be seen as one. You won’t always know
what to do in certain situations. How do you handle a conflict within your
team? There’s no one or right answer.
As the leader of your team or company, you’re in the best position to
assess the situation and make a decision that feels right to you. It’s
possible that you take the wrong decision, but that’s how it is. You win
some and you lose some. Learn from your mistakes, be transparent
about them, and move on.

Lead
Listening to the people you work with and asking for their input is
essential to building a healthy team or company. But always remember
that you’re the leader and you have final say when decisions need to be
made. And that’s what a team member expects from its leader. When
push comes to shove, you need to show that you’re the leader and the
man or woman taking the decisions.

This won’t always be easy, but it’s necessary. It’s as simple as that. You
won’t always know whether that decision is the right one, but that’s how it
is. That’s what sets a leader apart from a team member or an employee.

PART 6: CAREER

1 Open Source
The concept of open source has been around for decades, but platforms
like GitHub have accelerated the growth of open source initiatives. Most
of us can’t imagine a world without open source software.
Open source software can be a powerful instrument to promote yourself
as a developer. Many respected developers in the Cocoa and Swift
communities have gained name and fame through their open source
projects, think Eloy Dur n, Mattt Thompson, and Ole Begemann.

Start Small
If you’re new to open source, then I don’t recommend diving in head first.
Start small. I’m sure there are several open source projects you make
use of in your own projects. A good place to start is to explore the
documentation of these projects. That’s right. The documentation.
You’d be surprised by the number of open source projects that have
outdated documentation. This isn’t surprising since it requires a lot of
work to maintain an open source project. Because you’re already familiar
with the project, you can browse the documentation and fix any issues
you find on your path, including typos and grammatical issues. While this
may seem nitpicky, the author of the project will thank you for it.
Clone the project, make the changes, and submit a pull request. Make
sure you read the guidelines for contributing to the project first. Many
projects have a code of conduct to make contributions easier and reduce
friction.

Taking the Plunge
You may already have a library or project you want to share with the
community. Sharing something with the world can be scary, though.
Make sure you’ve cleaned up the project and don’t share any personal or

confidential information. When you share a repository with the world, you
give everyone access to its history.
For example, if you committed a private key or token at some point and
removed it later, then anyone with access to the repository can retrace
your steps and access that information. Remove the project history if you
want to play it safe. Once the information is public, there’s no way back.

Documentation
Most of us don’t spend much time documenting personal or internal
projects. That’s a decision everyone needs to make for themselves. An
open source project without documentation, however, won’t get much
traction. Not only is it difficult for anyone interested in your project to get
up to speed, it’s not a healthy sign.
Every time I look for a third party library to include in a project, I
immediately discard repositories without a proper README. It only takes
a few minutes to create a README and an additional hour to create an
installation and getting started guide. Not only does your project look
more appealing, you help anyone interested in your project.
You can take it one step further and add a sample application that shows
developers how to use your library. Anyone new to your library can play
with the bundled application and see for themselves how to use your
library and integrate it into a project.

Taking It Seriously
The commitment of some developers is admirable. They cover their
project with unit tests, set up continuous integration, and write pages and
pages of documentation. This is usually a community effort and that’s
what’s wonderful about open source software. Once your project gains
traction, developers automatically start giving back with small, or large,
contributions.
These contributions are very welcome, especially if you have limited time
to spend on your open source project. If you’re a freelancer or an
independent developer, then it can be a breath of fresh air to collaborate
with other developers on a project. That’s a bonus you get for free.

Giving Up Control
For some developers, the hardest part of open sourcing a project is
giving up some of the control they have over the project. You can decide
to manage everything yourself, but that isn’t feasible if your project
becomes popular. It also goes against the spirit of open source software.
To avoid that your project becomes messy and an odd collection of
coding styles, you should adopt and enforce a style guide. This isn’t
difficult to implement. When I submitted my first pull request to the
CocoaPods project, I immediately received automated feedback about
the coding style I was using. I took a look at the project’s style guide,
made a few changes, and submitted an update. Having a style guide
that’s automatically enforced helps to keep your project consistent and it
keeps the maintainer(s) sane.

Taking Responsibility
One of the most challenging aspects of an open source project is keeping
it up to date. It takes time and effort to keep your projects up to date.
Automation can make this much easier. Know that several hosted
continuous integration solutions offer a free tier for open source projects.
If you’re serious about your project, then that may be worth looking at.
And remember that you don’t need to do everything yourself. For
Cocoacasts, I create many, many projects for the tutorials I write and
record. It’s challenging to keep them up to date. If a reader notifies me
that a project hasn’t been updated for the latest version of Swift or Xcode,
then I suggest that they submit a pull request. That’s not unreasonable. Is
it?
Open source is a community effort and everyone involved in a project
should take responsibility.

2 You Are the Constant in Your Career
One of the reasons for writing this book is that it allows me to talk about
subjects that are related to programming, software, and the life of a
developer. Even though they’re related, they’re often overlooked or
ignored. This is especially true for young developers. Don’t feel bad,
though. It’s natural and maybe even a necessary part of your evolution as
a developer.

Putting Yourself First
Most of your time is spent working for someone else, a boss, a manager,
or a client. The technology industry is known for long days and weeks
and sacrificing time with friends and family. But don’t let that distract you
from what’s important. What’s important isn’t the project you’re working
on or the client you’re building a mobile solution for. What’s important is
you. Why is that?
Many developers change jobs every few years. There are many reasons
for doing so. That’s not the point, though. No matter where you end up
next, there’s only one thing you take with you. You. You’re the constant in
your career. This may sound like a simple platitude, but it isn’t.
There have been times that I worked for the same client for several
years. It was good money, but I didn’t feel I was reaching the goals I set
for myself. I felt that I was stagnating as a developer, and that’s not a
good thing for a freelancer. The space is evolving at breakneck speed
and you can’t afford to stagnate.

Setting Goals
Every now and then, I set goals for myself to keep me motivated,
accountable, and to make sure I can objectively validate that I’m evolving
as a developer. I’m sure you have a few things on your list that you want
to learn, some day. Who’s keeping you accountable? How long have
these items been on your list?

Learning Requires an Investment
If you’re in luck, then you have the time to learn new things. You may
even have a boss or manager that explicitly asks you to investigate a
new technology to pick up.
Learning something new requires you to invest time and energy. You
need to allocate time to seriously look into and experiment with the
technology you’re learning.

Take Care of Yourself
Earlier I mentioned that long days and weeks are not uncommon in the
technology space. That’s fine as long as you don’t push yourself too
hard. Everyone has limits. I know what it’s like to feel invincible when
you’re in your twenties. That feeling of invincibility disappears gradually
as you approach your thirties and forties. Burning the midnight oil isn’t
something I’ve done in a long time. I’m too old for that.
I’ve been around developers for long enough to know and understand
how tempting it can be to only focus on the job. We live in times where
work is a valid excuse for ignoring other important aspects of our lives.
Working out or going for a simple walk is often more important and
sacrificed as a result.
It should come as no surprise that many of us suffer from a slew of
illnesses and subtle health problems, from obesity, diabetes, and back
problems to chronic fatigue and bad sleep. The underlying problem is
surprisingly often related to work, directly or indirectly.
If you’re in your twenties, then you probably think that I’m talking rubbish.
If you’re in your thirties, then you might already think a bit differently. If
you’re in your forties, then you’re probably nodding your head.

Looking Back
I’d like to end this chapter with a simple assignment. In December, I
always take the time to look back at the past year. The last weeks of
December are ideal for this exercise. Work is slowing down and many

people are taking some time off to spend with friends and family. But you
can do this exercise whenever you like.
Take a piece of paper and write down what you’ve accomplished this
year. Don’t use a computer or another electronic device. Use a pen or
pencil and a piece of paper. Which goals have you accomplished that
moved the needle for you? Not for your boss. Not for your clients. For
you.
What have you learned? Who have you met or spoken with that impacted
your way of thinking? What books have made an impact on the way you
think about your work as a developer? Give yourself ten to fifteen
minutes. Don’t stop too soon. The best stuff comes out after a little while.
Are you happy with the list you’ve compiled?

3 Build That Application
Do you have a folder on your machine that’s filled with unfinished
projects? Be honest. I know you do. I have dozens of unfinished projects.
Each of these projects started its life as an exciting idea, an idea I
absolutely needed to execute on.
When a fresh, exciting idea enters the mind of a software developer, it’s
hard to resist the madness. These projects often start with a few days or
weeks of hard work, very little planning, no business plan, and only a
vague idea of what the final result will look like.
These unplanned projects are great. I love working on them. The sad part
is that they almost always end up collecting digital dust, joining dozens of
other unfinished projects. Building is easy. Shipping is hard.

Build and Ship
Real artists ship. — Steve Jobs
Steve Jobs famously said that real artists ship their creations. You’ll find
this quote more than once in this book. It’s easy to come up with a
compelling idea, spend a few days or weeks building the product, and
shelve it, elegantly wrapping it in a promise to finish it when you have
more time.
It’s easy, but, more importantly, it’s safe. It’s safer because few people
are willing to show the world what they created. They fear the opinions of
others. They fear people are going to judge their product and, even
worse, its creator.

Show What You Can
When you’re applying for a job, showing that you have relevant
experience is often essential. Not too long ago, several years of

experience were mandatory for a job as a software developer.
Nowadays, employers are looking more and more at the portfolio of
potential candidates. This is especially true in software development.
People new to software development or graduates looking for their first
job may find it challenging to prove that they have experience developing
software. The truth is that they often don’t have the necessary
experience.
How do you solve this problem? How do you break this vicious circle?
Don’t wait for that first job or project to start gaining experience. Show
potential clients or your future employer that you have experience
building software. It’s never been easier to get started with software
development. What’s stopping you from creating?

Stay Ahead
While it’s fine to learn as you go, it’ll certainly help you if you know the
basics of the most common tasks of software development. Building and
launching a software product is quite an involved process. It doesn’t stop
the moment you have successfully built and deployed your first iOS
application on your iPhone or iPad.
Have you thought about beta testing, launch images, application icons,
and localization? If you can show your future employer that you have
thought of, built, and shipped a software project that’s polished and
carefully maintained, you’re almost certainly what they’re looking for. An
interview is almost guaranteed.

Rinse and Repeat
Apple’s App Store is filled with abandoned applications. Frequent
application updates are a sign to your customers that you’re building
something you care about and customers will automatically feel that you
also care about them.
It isn’t necessary to include a major feature in every update you ship.
Improving your application’s stability by fixing bugs is just as important as
focusing on features.

Localization is another aspect that’s easily overlooked. Did you know that
Japan is one of the most profitable markets for mobile applications?
Consider working with a translator to translate your application to
Japanese. It won’t cost you much and you’ll learn a lot from the
experience. Your Japanese customers will thank you for it.

Build That Application
I encourage you to start building and, more importantly, to start shipping.
Your first application doesn’t need to be perfect. What’s important is to
get it in the hands of your customers. Create something useful for others.
Refine what you’ve created and listen to your customers. What’s stopping
you? What are you waiting for? Gain experience by building and
shipping.

4 Protect Your Productivity
How productive you are as a developer isn’t only the result of your habits,
your talents, and your experience. Your environment plays a key role,
especially if you work in a team, a company, or a shared workspace.
Some developers thrive in a noisy or busy environment, but those are
usually exceptions to the rule. That rule is simple “Don’t interrupt the
developer.”

Working From Home
Working from home is a luxury if you have the discipline to set clear
boundaries for yourself. Unfortunately, it’s a very, very common trap
many people fall into, not only developers. When you make the switch
from working as an employee in a large office to working from home in a
small home office, if you’re lucky to have one, you may naively think your
productivity is about to skyrocket. The opposite is almost always true,
especially in the first few days or weeks.
Making a drastic change, such as moving into a home office, means that
you need to create new habits. Most of us believe it has everything to do
with discipline, but that’s only part of the equation. Take the time to create
a schedule that works for you and the people you work and live with. That
may mean that you start early or put in a few extra hours in the evening
when the kids are asleep.
You need to define boundaries, not only for yourself, also for the people
you live with. Working from home is still work.

Working In an Office
Working in an office has its pros and cons. The advantage is that
everyone knows and understands that you’re at work to, well, work. Make
it clear that you don’t want to be disturbed. Protect your productivity. This

may sound harsh, but it’s essential if you want to get meaningful work
done.
As a developer, your most important asset is your attention. If you’re
working on a complex task, it takes time to gain momentum and be
productive. Every time you’re interrupted, you need to start from square
one. Not only is this frustrating, it can be mentally taxing.
I once worked in an office that had a simple rule that said that a
developer with its headphones on shouldn’t be interrupted. A room filled
with people wearing headphones isn’t uncommon in the technology
industry where open offices are the norm. You’d be surprised by the
number of developers that wear headphones without actually listening to
music. It’s a trick I’ve used many, many times. This is especially effective
if your headphones have noise cancellation.
While this rule looks great on paper, it doesn’t hold up in most situations.
Everyone is interrupted dozens of times a day. The number of productive
hours we put in is much lower than you’d think. That’s the reality we live
in.

Minimizing Interruptions
Slack and email have become indispensable in most companies, large
and small. They’re great tools for communication if they’re used wisely.
They’re not most of the time. They’re surprisingly often used as
distractions instead of productivity tools.
Make sure you’re not distracted by a slew of, often unimportant,
notifications. If you’re constantly interrupted by notifications, then it’s
clear you have no intention of getting work done. Don’t look for
productivity hacks if you’re not serious about the most fundamental
elements.

Find a Quiet Place
If you have a deadline to meet or you absolutely need focus, then looking
for a quiet spot in the office may be your last resort. This isn’t a solution
long term, but it’s sometimes your only option. If you’re in luck, you may

find an empty meeting room, but a couch or the kitchen is fine too. Don’t
forget to bring your headphones.

Deal With It
Distractions and interruptions are part of the world we live in. Working in
the technology industry means that you’re in the eye of the storm.
There’s no perfect solution unless you work from a home office where
you dictate the rules.

5 Building Your Portfolio
A portfolio is one of the most important assets of any developer with
ambition. Mobile applications, for example, are so commonplace that
potential employers or clients will want to see what projects you’ve
worked on in the past. Aspiring developers often ask what they should
show if they haven’t created any applications yet. The answer is simple.
Start creating.
If you’re learning the ropes of software development and you don’t have
any clients yet, then what are you doing all day? You don’t need to learn
everything there is to know about software development to start your first
project.

Scratch an Itch
While not every idea will be a runaway success, the itches you have are
perfect for your first projects. If you’re just getting started, then it’s
important to choose a relatively easy problem to solve.
The first application I shipped was an iPad application that allowed users
to import and tag images from an Aperture or iPhoto library. While I did
eventually publish the application, it was a bit too complex for a first
project.
Start small and build larger, more ambitious projects as you grow as a
developer. By biting off more than you can chew, you may lose motivation
or become discouraged.

Setting Goals
The primary goal of your first project should be simple, creating and
publishing an application that provides value to people. You can set
secondary goals, such as trying to monetize your application or climbing
the charts of the App Store. Those goals are less important, though.

Monetizing your application is only possible if you share it with the world,
which means you first need to build and ship an application.
I love running. Every time I go for a run, I have three goals. The first and
most important goal is to enjoy the run. The second goal is to finish the
run. And the third goal is to beat my best time.
In the early stages of your career, it’s important to approach software
development with the same mindset. Make sure you enjoy what you’re
doing. If you don’t, you won’t stay committed to learning your craft. It
shouldn’t feel as a struggle. I dare say that it shouldn’t even feel like
work.
It shouldn’t feel as a struggle.
The second goal should be to complete the project you’re working on.
Once you commit to a project or idea, it’s important that you stick with it.
Steve Jobs famously said “Real artists ship.” As a developer, you’re
creating. That also means that you need to ship your creations.
Real artists ship. — Steve Jobs
The third goal is the proverbial cherry on the cake. That goal may be
hitting the top charts in your application’s category or reaching a certain
number of downloads. That’s up to you.
Why am I giving you this advice? And what gives me the authority to give
you advice in the first place? Ask any developer how many projects they
started but never finished. Starting projects is fine. But sometimes you
need to ship. Do you want to be taken seriously as a developer, then you
need to be able to show that you can start and finish something.
Do you want to be taken seriously as a developer, then you need to
be able to show that you can start and finish something.
Whenever I interview a developer for a project, I ask them about their
previous projects. Your future employer or clients will do exactly that.

Even if you plan to start as a junior developer or an intern at a company
or agency, it plays to your advantage to show one or more projects you
started and finished successfully. It makes a world of difference. Why?
Because finishing something is harder than it seems.
If software development is part of your DNA, then you’ll be able to start
and complete your first software project. Most developers have a hard
time stopping themselves from creating cool software or using the latest,
fancy libraries. Despite this drive to create, it’s equally important to finish
and ship. I cannot emphasize this enough.

Learn the Basics
A question that comes up often is whether you should dive in head first or
learn the basics. The answer is, “Both.” It’s key that you know the
foundation of the language you’re using, but it’s also important that you
start creating as soon as possible. I explain this in more detail in the first
chapters of this book.
Apple’s platforms are so accessible that I guarantee you that you can
create a basic Cocoa application the day you start learning Cocoa
development. There’s no need to read The Swift Programming Language
from cover to cover. It’ll discourage you since you started with Cocoa
development to create cool things. My suggestion is to choose a guide
that teaches you Swift as you learn the ropes of software development.
The sooner you see the bigger picture, the sooner you’ll feel comfortable
on the path you’re taking.
There is one big but, though. If you only focus on creating things and
don’t take the time to learn the more intricate aspects of the platform,
you’ll end up creating bugs, missing best practices, and, in the end, being
frustrated why something isn’t working. Remember what I wrote earlier,
“Don’t ignore your foundation.”
Learning a human language is easy at first if you only focus on
memorizing words and sentences. Your memory is only able to take in so
much, though, and what are you going to do if you run into a situation you
don’t know anything about?

Most language courses start with simple sentences to give students the
feeling that they’re making progress. Sooner rather than later, the teacher
teaches them about spelling and grammar, explaining the sentences they
learned from a grammatical point of view.
The gist is that you need to become familiar with the basics, the
foundation, if you want to grow as a developer. It isn’t always as
interesting as learning the cool things, but it’s just as important.

But Start Creating
No matter what path you choose or what language you learn, it’s
important to start creating. Set a goal, pick a problem you want to solve,
and build a solution. That’s what software development is about.

6 How Badly Do You Want It
It isn’t easy for inexperienced developers to find an attractive job without
years of experience or an impressive portfolio. That shouldn’t be an
excuse, though. It’s never been easier for developers to build a portfolio,
gaining experience along the way. In this chapter, I show a few examples
of how you can build a portfolio and gain experience to help you find
clients or impress your future employer.

Contribute
Whenever I vet a developer, I take a look at their past work. Open source
contributions are ideal for this. It isn’t necessary to build an open source
project from the ground up, though. Engagement and taking responsibility
in existing open source projects is a good first step.
Many well known developers have gained name and fame by creating
and maintaining open source projects. Eloy Durán, for example, had
years of experience as a Ruby developer and missed a reliable
dependency manager for Cocoa. Instead of complaining about it, he
created CocoaPods and turned it into the most popular dependency
manager for Cocoa development.
Open source projects often die a quiet death due to the lack of
contributors. But another common reason is the absence of good
documentation. Nothing stops you from creating a pull request to update
the README of an open source project to polish its documentation.
Developers new to the project will thank you for it and so will the
maintainers of the project.

Build
It’s never been easier to create software. Getting started with software
development isn’t that hard. What’s stopping you from creating your first
mobile application? If you’re looking for a job, then your future employer
will ask you about your portfolio.

Finding clients is hard without a portfolio. Would you hire an architect
who has never built a house before? The fact that you’re looking for your
first job as a software developer or freelancer isn’t an excuse for not
having a portfolio with one or two applications. Build that application.

Maintain
Being a software developer also means that you’re responsible for
maintaining what you create. It isn’t necessary to ship a new feature
every month. What’s more important is making sure existing users are
happy and stay happy.
Take a look at the crash reports of your application. Are there any issues
you can fix? What are people complaining about? Could you improve the
onboarding experience?
Being able to show that you have the skills to build and maintain a
software project goes a long way. Not only will your future employer look
for these skills, you also need them to excel as a software developer.

Plan and Manage
If you want to take it up a notch, then scheduling releases and adding
features is the next step. The idea is to start simple, build a modest user
base, and improve the application over time. Listen to the users of your
application, sift through the feature requests, and decide which features
make the cut. Remember that you manage the project, not the users of
your application.
Test a new feature before releasing it to the public. Involve your existing
users by distributing a beta build of the application through Fabric,
Hockey, or Apple’s TestFlight.
Adding support for multiple languages is another great improvement that
underlines your commitment to the project. This may involve hiring a
translator.

Gain Experience

Getting started with software development is easy. Starting from zero and
publishing an application on Apple’s App Store requires effort and
perseverance, though. It means that you cannot quit halfway when you
don’t feel like finishing the project. Every developer has a slew of projects
they started working on and never finished.
Finishing is hard, but that’s exactly what your future employer or potential
clients want to see. There’s nothing more enjoyable than starting a new
project, but it takes grit and tenacity to finish a project and click the
submit button to publish your creation on the App Store.
It’s to finish a project and ship something people can use. It can be scary
to share your work with your peers, but that’s what it takes to succeed.

Be Yourself
There’s no need to compete with your peers. If you continue to do what
you love and what you’re good at, you will get where you want to be. But
remember that you only get what you work for. If you aim for mediocracy,
then that’s what you’ll get. If you aim for the best …

How Badly Do You Want It
Whether you succeed depends on the question “How badly do you want
it?” Are you willing to work nights and weekends? To make a dent, you
will need to go beyond showing up.
Showing up is overrated. Necessary but not nearly sufficient. — Seth
Godin
It’s important to be honest with yourself and define what you expect from
your career as a software developer. Gary Vaynerchuck is spot on when
he says “If you live for weekends or vacations, your shit is broken.” Is that
you or are you aiming higher?
If you live for weekends or vacations, your shit is broken. — Gary
Vaynerchuk

What About You
Are you motivated to get off your butt and make awesome stuff? What
are your goals and dreams? You don’t know? Then that’s the first thing
you need to sort out.

7 Freelancing and Subcontracting
Making a living as an independent freelance developer is great, but it can
be a tough job at times. What I enjoy most about freelancing are the skills
you learn to master, or better, are forced to master. A team of one has its
upsides and its downsides.

Freelancing and Subcontracting
As an independent freelance developer, you spend a significant chunk of
your time doing tasks that don’t involve programming. If programming is
what you want to focus on and you have the ambition to run your own
business, then you may want to consider subcontracting?

What Is Subcontracting
A subcontractor is an individual or in many cases a business that
signs a contract to perform part or all of the obligations of another’s
contract. — Wikipedia
The above definition sums it up nicely. As a subcontractor, you are hired
by another company to carry out work for one of their clients. Why would
a company do that? There are a number of reasons. The most common
ones are a temporary shortage of manpower and a lack of expertise in a
particular field.

Why Consider Subcontracting
It’s true that, at times, it feels as if you’re an employee of the company
you work for. Subcontracting isn’t for you if that’s a compromise you’re
not willing to take. I can see why you don’t want to go that route as an
independent freelancer. As a subcontractor, you run a business while, at
the same time, you’re working for another company. There are several
notable benefits, though.
Change of Environments

One of the advantages of subcontracting is the change of environments. I
don’t mean a change of scenery, but a change of development
environments. By working at different companies, you come in contact
with a wide range of people and company cultures. You learn the pros
and cons of the tools they use, the workflows they apply, and the best
practices they live by.
Even if you’ve been programming for years and years, you learn
something from every company you work for. There’s always someone
who’s smarter than you and who you can learn from. This is a benefit of
subcontracting that’s often overlooked. As a developer, it’s one of the
most important benefits if you ask me.
If you enter a contract with the mindset of knowing everything you need
to know, then this free benefit isn’t for you. That said, if you ever come at
a point where you think you know everything there is to know about your
craft, then it may be time to evaluate your current situation. I have yet to
meet someone who knows everything about their craft. The more you
learn, the more you realize how little you know.
Focus on What You Love

As I mentioned earlier, an independent freelance developer needs to
master a wide range of skills to run a successful business. Finding leads,
talking to customers, and writing proposals and specifications are but a
small subset of the things you do as a freelance developer and business
owner. Some people love that mix of responsibilities. If that’s you, then
subcontracting may take some getting used to.
But if you started freelancing because you enjoy programming more than
anything else, then you may not like those responsibilities all that much.
In that case, subcontracting could be a great fit for you.
In larger companies, developers can focus on what they do best,
programming. A project manager takes care of client relationships, the
sales team makes sure new projects are lined up for you, and the
operations team handles the infrastructure.

Choose Your Clients

The company you work for as a subcontractor is your client. The
company’s clients are not your clients. Before you decide to subcontract
for a company, take a look at the company’s portfolio. It’s fine to be picky,
especially if you have a portfolio you can be proud of.

Subcontracting or Employment
The line between subcontracting and employment may seem thin at
times. This is especially true if you’ve been working for the same
company for months or years. There’s nothing wrong with that, but it’s
important that you feel comfortable in that situation.
If subcontracting begins to feel like employment without the benefits of
being an employee, then it may be time to find another project at a
different company or choose a different path altogether.
If this really bothers you, then being an independent freelancer may be a
better fit. Nothing stops you from mixing subcontracting with working as
an independent freelancer. Many freelancers do. The line between
subcontracting and freelancing is sometimes pretty thin.
Both paths will teach you more than you can imagine. But make sure you
don’t become complacent. That’s my one advice. If you choose a
particular path because it makes your bank account happy, then it’s time
to reconsider your choices and priorities.

Being Picky
Elsewhere in this book, I explain which steps you need to take when you
inherit a software project. If you’re working as an employee at an agency
and your company acquires a client from a competing agency, this often
means that you also acquire one or more existing projects. This is usually
part of the deal. As an employee, you have very little say in the matter.
Inheriting a software project is rarely a gift.
Things are a bit different as a freelancer. You have the luxury and
freedom to choose who you work with. For example, I no longer take on
existing projects because it usually means several days, weeks, or
months fixing bugs, making minor improvements, and spending a lot of

time fixing issues. I understand that not everyone has this freedom, but
it’s important to know that you can be picky if you choose to be.
Being picky doesn’t only apply to projects. You can also be picky when it
comes to the clients you work with. Working with individuals with a small
budget is rarely worth your time. Not because these people aren’t fun to
work with, but because they have no experience in the space and have a
limited budget to spend. Their focus is almost always on limiting costs
and understandably so. The quality of the product is secondary. This
means that the developer needs to work fast, cut corners, and almost
always defend their decisions.

Taking a Peek
If you do decide to work on an existing project, I strongly recommend that
you take a look at the project first. This usually isn’t a problem. If it is,
then that may be a red flag for you.
Taking a look at the project usually means signing a non-disclosure
agreement. That’s fine, but make sure you carefully read the agreement.
You’re only vetting the client and their project. Don’t take any risks and
don’t commit to anything you don’t feel comfortable with.

Is It Worth It
Instead of taking on the project, have a conversation with the client to get
an idea of the amount of work they can bring in over the next months. Be
careful, though. I have spoken with many potential clients that promised
more work in the future and never delivered. That’s why I never start a
relationship with a client based on a project that only involves bug fixing
and minor improvements. I understand that such an assignment is ideal
for the client to test the waters. I see that a bit differently.
If a client approaches me for a collaboration, I expect them to trust me.
They contact me for my expertise and I have no intention of convincing
them that I’m a good fit for the job. If they feel I’m not, then they shouldn’t
have contacted me in the first place. Does this seem arrogant or
complacent to you? Think again. I consider it a form of trust and respect.

Firing Clients

Most freelancers have the feeling that a client chooses them to work on a
project. This is usually true if you don’t have many projects lined up or if
you’re just starting out. Earlier I wrote about being picky and that also
applies to clients.
As a freelancer, it’s important to remember that you’re on your own. No
matter how good your relationship is with your client, they will let you go if
they feel that’s the best decision for their company. This means that you
should always put yourself first, not your client. This applies to your
health, your workload, and your mental sanity.
I’ve always been confused by the use of “freelancer” and “consultant”.
While there is a difference, a good freelancer is also a consultant. An
experienced freelancer is worth its weight in gold and a client should be
lucky to have you. With that attitude, your relationship with the client
changes dramatically. You no longer feel that you should only do what
you’re told. You should also advise the client.
If you feel that your input and your advice are ignored by the client, then
you may be starting to wonder why you chose to become a freelancer.
When there’s an issue with my car, I trust my mechanic to decide what
needs to be done. A professional listens to the client and then decides
what should be done. If the client doesn’t respect your advice and insists
that you do what they think is best, then you may want to fire the client.
Wait. What? Fire the client?

Fire the Client
Firing a client is a new concept for many freelancers and subcontractors.
It can be a scary thing to do, but if you feel that you’re having an
unhealthy relationship with your client, then consider taking action to
change the situation. Having a conversation is obviously your first step,
but, if that doesn’t bring significant change, then you should consider
moving on.

PART 7: PRODUCTS

1 Ship, Ship, Ship
Steve Jobs famously said “Real artists ship.” He meant that putting your
work out in the world is an essential aspect of every creative, and that
includes developers. Creatives that only work in isolation and never ship
anything may not be that real after all.
Earlier this year, I sent a survey to Cocoacasts readers to learn more
about what they do, what their goals are, and where they’re currently at. I
also asked them about any applications they have in the App Store.
Many of us have published some personal projects, but the most
common answer to the question was the goal or ambition to have an
application in the App Store. It’s common to start something without ever
finishing it.

It’s Hard
I’ve written about this many, many times because it’s something that
fascinates me. Developers are creative people, and we have an urge to
create. Unfortunately, most of us stop when we lose interest. Motivation
isn’t what’s going to get you from idea to App Store. It’s grit, tenacity, and
persistence.
Solving a problem is what we like to do. Writing release notes,
implementing in-app purchases, or localizing an application isn’t what we
enjoy most. But it’s an essential aspect of software development.
Unfortunately, it’s what stops most of us from shipping.

How to Ship Consistently
Over the years, I’ve built many, many applications and some of them
made their way to the App Store, not all. It has taught me several useful
lessons that guarantee that I ship stuff consistently.

Make It Tiny

It’s fine to dream and to be audacious. But Rome wasn’t built in a day.
What stops many of us from shipping our creations is aiming too high. I
don’t mean to say that you shouldn’t aim high. What I am saying is that
you should aim for consistency.
My latest application is focused and to the point. I have big goals, and
even dreams, for this application, but the first release focuses on the
essentials. I interviewed people that are interested in the product and
asked them which features were essential for them to use the application.
I analyzed the results, went to work, and plan to ship the first version of
the application later this month.
It’s fine that your application is limited in scope. That’s much better than
no application at all. Right? I’m convinced that there are thousands of
applications collecting dust on people’s computers because they aimed
too high for the first release. Keep it small and focused.

Ship Frequently
Once you have something in the App Store, it’s surprisingly easy to
iterate on what you already have. Define the scope for the next release,
keep it focused and small, and ship. Rinse and repeat. Listen to feedback
and improve the application as you go.
It’s an approach that has worked very, very well for me. It also shows my
customers that I’m continuing to invest in the product. It builds trust and
confidence. The App Store is littered with abandoned applications that no
longer receive updates. One of my favorite utilities stopped working after
I updated my phone to iOS 11.

Keep the Bigger Picture in Mind
Shipping frequent, focused updates is very effective, but make sure you
keep the bigger picture in mind along the way. Avoid ending up with a
product that packs dozens of features but lacks a clear direction. You’re
the product owner and it’s your task, not your customers’, to give
direction.

Internal Deadlines

I sometimes make the mistake of publicly committing to a deadline. This
strategy works for drawing attention, but it’s detrimental for your sanity.
What works much better is setting internal deadlines, which I discuss in
the chapter on source control. It works well in teams, but it’s also an
effective strategy for personal projects.
The idea is simple. Schedule releases on a regular basis and ship what’s
ready. That’s the gist. If you adopt the branching strategy I describe
elsewhere in this book, then that’s simple to implement. Combine this
with a dash of automation, and you have yourself a shipping machine.
Such a workflow lets you focus on what you enjoy doing most, building
amazing software.

Remove Friction and Clutter
There are numerous tasks you need to handle if you’re building and
shipping products. It can be a chore to prepare a release. To make this
easier, I automate most of the trivial aspects of a release, such as
translation management and creating and uploading screenshots.
Manually creating and uploading screenshots is virtually impossible if you
want to support every device your application can run on. You’re a
developer and you should be automating repetitive tasks.
It pays off to set aside a few hours from time to time and automate your
workflows. I write more about this aspect of software development in the
chapter on automation.

2 Talk to Your Customers
As developers, we have the itch or the need to analyze problems and
craft solutions for them. That’s what drives most developers. If you boil it
down to its essentials, then a developer solves problems, large and
small.
Some of us have bigger ambitions, though. What has always appealed to
me most is the possibility of creating a product and selling it to hundreds
or thousands of people. Apple gets a lot of flak for taking a significant cut
from your earnings, but, credit where credit is due, Apple has made
creating and distributing software easier than ever. It’s no coincidence
that the App Store catalog packs millions of applications. Whether that’s
a good thing is a different discussion.

Solve a Problem
There are many reasons for publishing an application on Apple’s App
Store. Some developers want to test the waters, create a portfolio to
show future employers, and some of us want to help others for free.
Some of us have the ambition to turn our passion into a business. To be
honest, I’m always suspicious when I see “passion” and “business” in the
same sentence. I believe that you can be passionate about the thing that
makes you money, but passion and business can be a dangerous or
misleading combination.
Every business starts with an idea. But a successful business starts with
a problem. Ignore Facebook and Twitter for now. I hope you don’t have
the ambition to create the next Facebook or Twitter.
As I mentioned earlier, a developer is wired to solve problems. Some of
us also have a gift to spot problems, which can be both a curse and a
blessing. But the first mistake developers make is trying to come up with
an idea. And many people I’ve talked to get frustrated in this phase.

The solution is surprisingly simple. Turn it around. Instead of looking for
an idea, look for problems and try to come up with a solution. That’s the
seed for a successful business. Why is that?
As developers, we’re focused on the technical aspects of the product.
We’re so immersed in the process of solving the problem that we forget
to ask the most important question. Does anyone want what we’re
building? And this leads to a waterfall of other equally important
questions. Who is the person we’re helping? What is the pain they have?
And how are we trying to make that pain go away?

Ground Zero
Your first task is to validate your idea. It determines whether you will
spend the next days, weeks, or months creating a business or a fantasy.
Every developer I’ve talked to about creating a product business has
made this mistake. Every. Single. One. I’ve made this mistake several
times, even after I knew I had to validate the idea first. It’s just incredibly
tempting to fire up a code editor and start coding.

Is This for You
If your passion is writing code, then building a product business may not
be for you. You have to be honest with yourself about this. Building a
business also includes marketing, customer support, writing release
notes, and much more. You don’t need to be passionate about these
responsibilities, but you need to take care of them. I don’t like marketing,
but I know it’s essential for my business.
The same applies to freelancing and working as an employee.
Freelancing looks amazing on paper, but a freelancer needs to find
clients, write proposals, and a lot of administration. That’s why most
developers work as employees at a company where they can focus on
what they enjoy doing most. And that’s fine.

But It’s Fantastic
Even though running a product business is hard work, and a lot of it, the
feeling of creating something people are willing to pay for is amazing.

You have the feeling that you’re making a dent in the universe, a tiny one,
but it’s still a dent. You’re doing something that matters and that helps
people in their lives.
And that too can turn into a passion. Being passionate about your
business sounds much healthier than trying to turn your passion into a
business.

A Recipe for Success
While building a successful business is hard work, there is an easy
blueprint you can use. It doesn’t require venture capital, and you don’t
need to have thousands of followers on Twitter. The recipe is simple.
Step 1: Find a burning problem people have.
Step 2: Solve that problem.
Step 3: Ask for money.
This roadmap isn’t rocket science. Unfortunately, the path most
developers that turn entrepreneur take is the following.
Step 1: Come up with an idea, not a problem.
Step 2: Build a product, not a solution.
Step 3: Release it.
Step 4: Frantically look for potential customers.
Step 5: …
Like most freelancers, people occasionally contact me to talk about an
idea they have for an application. They’re prepared to spend thousands
of dollars of their savings into a product that hasn’t even been validated
yet. They haven’t talked to a single potential customer. This is a recipe for
disaster.
As a rule, I don’t take on projects I don’t believe in. It isn’t fun to see
someone pour their savings into a project that isn’t going anywhere. Don’t
make this mistake yourself. Talk to your customers.

3 What Is Stopping You From Shipping
Earlier in the book, I wrote about building and shipping something, putting
something into people’s hands. I understand that life gets in the way from
time to time, but I’m genuinely wondering if you’re creating something.
I’m not referring to the work you do for your employer or your clients.
What I’m speaking about is the creative process of finding an itch,
coming up with a solution, and creating a product that scratches that itch.
Your product doesn’t need to change the world. You can start small. But
you have to start. What are you working on? What itch are you
scratching?

Why Is This Important
Building and shipping a product is something I write and talk about
frequently because I believe it’s important for every Cocoa or Swift
developer to be familiar with the life cycle of a product, from start to
finish. It’s true that you’re a developer, but that doesn’t mean you should
ignore other aspects of product development.
In medium to large companies, people often have the luxury to focus on
what they do best and enjoy doing most. But I don’t see this as a luxury. I
firmly believe that a key strength of most freelancers and independent
developers is their deep understanding of what it means to ship a
product, from idea to App Store.
I firmly believe that a key strength of most freelancers and
independent developers is their deep understanding of what it
means to ship a product, from idea to App Store.
It can be tough and frustrating to have to manage every aspect of the
product’s life cycle, but it’s also interesting. It teaches you a lot about
your craft, and you develop skills that make you an attractive hire. If you

don’t have the opportunity to be more involved in product development at
the company you work, then you can, and should, create a product of
your own.

Start Small
Having big dreams is great. It’s admirable. We need people with vision
and ambition. But everything starts small. Thinking big isn’t a problem as
long as it doesn’t distract you from the work that needs to be done today.
Big goals always start small.
Big goals always start small.
Start small by focusing on that one feature that sets your application
apart from every other application. How can you make it stand out? What
can you do to bring value to the user of your application with that one
feature? Not two. Not three. Only that one feature.
By intensely focusing on one piece of functionality, you force yourself to
make that one feature great, to make it magical. It’s fine to add bells and
whistles, but they shouldn’t distract the user from center stage.
Apple’s original iPod put the company back on the map. It was a
revolutionary product. It’s true that it looked amazing and that it was easy
to use. But, at its core, it did one thing very, very well. Playing music. The
product was focused. Apple removed every bit of clutter that could
potentially distract the user. Focus is what made the iPod stand out from
the rest of the market.

Remove Clutter
Many projects have a list of features that goes on and on. And that’s fine.
But is the feature list of your project stopping you from shipping? Are you
delaying the launch of your project because of one or two features that
your application can probably do without?
If your project needs a dozen or more features to add value, it may be
time to go back to the drawing board. If you need the bells and whistles
to cover up that center stage isn’t that great, you have missed the point.

Too many features is all too often the cause of missed deadlines and a
product that isn’t being shipped. I’m currently wrapping up a brand new
application. Some of the people testing the application are asking for an
Apple Watch application. I plan to support Apple Watch, but the first
version won’t include this feature. I know it will take me several weeks or
months to add this feature and that’s not what I have in mind. I want to
have this application in the App Store before the end of this month.
By postponing support for Apple Watch I make sure I can ship the
application sooner, but it also allows me to focus. Focus is a word you
find very often in this book. It has become an essential ingredient to
success in today’s day and age. I know it has for me.
What is stopping you from shipping?

4 Motivation Will Get You Only Halfway
I bet that you started more projects than you can remember. How many
of those projects have you finished? How many applications did end up in
the hands of customers?
You’ve probably heard the phrase “Follow your passion.” or “Do what you
enjoy doing.” I agree that you should do what you enjoy doing, but you
also need to know that passion often isn’t enough to go from idea to
product, a product people can use and find value in.

Motivation Won’t Cut It
As developers, we tend to launch a code editor whenever we have a
brilliant idea, coding away to solve the problem at hand. This impulse
usually lasts for a few days or weeks. If you’re lucky, you can motivate
yourself until you have a working prototype you can share with friends or
family.
A prototype isn’t enough, though. Building a product people can use
requires much more than a rudimentary version that solves a problem.

Running a Marathon
Perseverance, tenacity, and grit are qualities that are often undervalued
or overlooked. Your boss or clients don’t pay you because you’re
passionate or motivated. They pay you because you convinced them that
you can get the job done.
Building a product, shipping it to customers, adding features, and fixing
bugs are essential components of creating a successful product. Few
developers get excited by bug or crash reports. The truth is that your
code contains bugs and your application crashes if it has any complexity
to it. Even though fixing bugs and investigating crash reports are less
enjoyable tasks, they’re integral aspects of software development.

Creating a product isn’t a sprint. It’s a marathon with many ups and
downs.
If you’re waiting for motivation to kick in before you start working on those
bug reports, you’re probably waiting in vain. It requires perseverance to
take a project from idea to shippable product. It takes tenacity to iterate
on a product, to fix bugs, and add features.
Creating a product isn’t a sprint. It’s a marathon with many ups and
downs. It’s fine to start with a sprint, but you need to remember that
you’re in it for the long run.

Pulling the Plug
Not every product is going to be a success. The App Store is littered with
failed and abandoned projects. Not too long ago, Apple and Google used
the number of applications in their mobile stores to market their
platforms. Sadly, this is no longer something to brag about. Apple is
actively removing applications that no longer comply with the App Store
guidelines. Apple has realized it’s time to focus on quality instead of
quantity.
Even though Apple’s App Store contains millions of applications, finding
what you’re looking for is difficult. Finding an application that’s frequently
updated and fits your needs is even more challenging.
It’s fine to pull the plug on a product if you believe it’s no longer worth
pursuing as long as it isn’t an excuse to work on the next brilliant idea
that enters your mind. This is commonly referred to as the shiny object
syndrome.

Start and Persevere
I’ve written about building and shipping products quite a few times in this
book because it’s something I frequently struggle with. Adding features is
nice, but updating translations, making screenshots, tracking bugs, and
responding to customer feedback is much less glamourous.
Building and maintaining a product is more than worth it, though.
Samsara, for example, has been around for several years and people still

email to tell me how much they enjoy using it for their yoga and
meditation practice. These emails get me excited to continue improving
Samsara with every release. It gets you through the tough times when
motivation is low.

Challenge Yourself
Most developers thrive when they’re faced with a problem they need to
solve. Continue to challenge yourself. Pick up a new language or explore
a new library to keep you sharp. Solving problems is exactly what
software development is about. Is it not?

5 How to Make a Living as a Mobile Developer
Developers often refer to the early days of Apple’s App Store as the gold
rush of the App Store. Paid applications were the norm and prices were
much higher than they are now. What options do you have as a
developer or entrepreneur in today’s App Store? Is it possible to make a
living as an independent developer? In this chapter, I list the options you
have to make money from your applications in Apple’s App Store.

Paid Up Front
The most common approach to make money on Apple’s App Store used
to be asking users for money. Really. It sounds too crazy to be true.
Asking for money in exchange for a product is crazy. Joking aside, from a
business perspective, this makes perfect sense, and it comes with
virtually no overhead from the developer’s perspective.
To make money in Apple’s App Store, paid applications were the norm for
the first few years. This period ended with what’s now known as the race
to the bottom, developers competing with each other by cutting the
prices of their applications. The race to the bottom forced developers and
businesses to find other ways to make money.
While I’ve played with Samsara’s pricing, it has always been paid, and it
has done pretty well compared to the majority of applications out there.
While paid applications still have a future, it’s a less popular option these
days.

Freemium
The freemium model predates the mobile era. Desktop and web
applications used the freemium model long before the iPhone was
introduced. The idea is simple. You offer a product for free, getting it in
the hands of as many people as possible. To generate revenue, you do
your best to convince a subset of your users to pay for a premium
experience.

Offering the product for free has two important benefits. Your product
spreads faster and more easily, and you have a foothold in the
customer’s life.
How you define a premium experience depends on the product.
Evernote is a fine example of a company that has successfully applied
the freemium model. The company has tens of millions of customers. A
fraction of those customers pays for Evernote’s premium services. The
company would have had a harder time gaining market share if it had
offered its suite of products paid up front or with a monthly subscription.
Freemium isn’t without risk, though. For years, Rob Walling has been
warning developers and entrepreneurs that freemium is difficult to pull off,
especially for small, bootstrapped companies.
If your product has a backend, for example, then keep in mind that
customers that don’t pay for your product also make use of that backend.
Hosting costs can skyrocket if your product gains traction. In that case,
the conversion rate of free to paid customers will determine whether your
business is viable in the long run.

Advertising
Another widespread business strategy is advertising. You offer your
application for free and display ads to your customers. This business
model only works if your application has lots and lots of users and if your
users frequently use your application.
Games are a good fit for ads. Flappy Bird showed that developers can
potentially make millions of dollars through advertising as long as the
application has enough users that frequently play the game. Flappy Bird
was incredibly addictive, and that was the key to its short success.
David Smith is a successful, independent developer and he published a
very interesting article about how his business has evolved over the
years. In the early days of the App Store, the majority of David’s revenue
came from paid applications. Nowadays, advertising brings in most of the
revenue.

The market has been pulling me along towards advertising based
apps, and I’ve found that the less I fight back with anachronistic
ideas about how software “should” be sold, the more sustainable a
business I have. — David Smith
For Overcast, Marco Arment has experimented with several business
models, including advertising. At the time of writing, Overcast displays
ads, which you can remove by subscribing to Overcast Premium. The
ads shown in Overcast are managed by Marco himself and are primarily
targeted at podcasts. He recently mentioned on ATP that this is working
very well for him. It’s interesting to see this change and it shows that you
can make changes to the business model of your products as the space
you’re in evolves.

In-App Purchases
Selling virtual items is a very common monetization strategy in mobile
games. Most of the games that top the charts of the App Store make
money through in-app purchases. It’s a bit ironic to see a free game at
the top of the Top Grossing chart, but that’s the reality.
You can use in-app purchases for many purposes. Some applications are
free to download and offer premium features through in-app purchases.
This approach is very similar to the freemium model we discussed earlier.
Other applications display advertising, offering the option to remove ads
through an in-app purchase.
Whether in-app purchases work for your product depends on your value
proposition and it requires a bit of experimentation. If you only show a
tiny ad in the settings view of your application and you offer an in-app
purchase to remove it, then the chances are that people are fine seeing
the ad every now and then. Don’t discard in-app purchases if you feel it
isn’t working. It may take a few tries to get it right.

Subscriptions
Few mobile applications make money through subscriptions. If your
application offers a service that continues to be of value to the customer,
then offering a subscription makes sense.

Subscriptions are the holy grail in my opinion. They are great for building
a sustainable business. Instead of starting from zero at the start of every
month, you build up MRR or monthly recurring revenue. With a
predictable, recurring revenue stream, building a business becomes a bit
less risky.
If that’s true, why aren’t subscriptions more common in the App Store?
Netflix offers subscriptions because its customers watch movies and
shows on a daily or weekly basis. The company adds new movies and
shows almost daily.
Most mobile applications can’t offer a similar value proposition. A camera
application, for example, isn’t a good fit for a subscription model.
Customers expect to buy a camera application once and use it as often
as they want.
The landscape is changing, though. Last year, Apple announced that
auto-renewable subscriptions are now available for most applications in
the App Store. Also, after the first year, the developer’s cut increases
from the usual 70% to 85%. It seems Apple is encouraging developers to
experiment with new business models, including subscriptions. It shows
that Apple understands that the market is changing and evolving.

Donations
A small group of applications generates revenue through donations. With
the release of Overcast 2, Marco Arment made its popular podcast client
free. He introduced a patronage model in Overcast 2 to generate revenue
from his product. To the surprise of many skeptics, patronage seemed to
work for Overcast. But Marco wasn’t entirely happy with the low
conversion rate and he started experimenting with advertising and autorenewable subscriptions.
Marco’s reasoning makes perfect sense. He wants to offer the best user
experience to everyone that chooses for Overcast. He doesn’t want to
offer an inferior user experience to people that don’t pay for the premium
features or, more importantly, to those that haven’t decided yet whether
Overcast is right for them. It makes sense, but I wonder how viable
patronage or donations are for niche applications or applications with a
smaller audience.

I’ve considered this approach in the past for Samsara. A patronage
model would be a good fit, offering the best possible user experience to
every user. From a developer’s perspective, it’s a compelling idea.

Finding the Right Business Model
Every application is different. Not every business model is a good fit for
an application. If you’re creating a camera application, then offering a
subscription is probably not going to work. Using in-app purchases to
unlock premium filters is a more viable business strategy.
It’s worth spending time considering your options and experimenting with
different business models. It’s fine and possible to make your application
paid up front and switch to freemium down the road.
It felt hopeless, but my initial thinking was restricted by trying to
wedge traditional software business models into the realities of
today’s App Store. It’s hard to make older revenue models work
today because the market is completely different. — Marco Arment
Experimenting is fine, but make sure you don’t burn the goodwill of
existing customers. If you switch from paid to freemium and force your
loyal customers to unlock premium features they already paid for, then
prepare yourself for a flood of angry complaints.

Experiment But Be Smart
Always keep your customers in mind. Don’t switch business models with
every major release. Does that mean you can’t make changes to the
business model of your product? Absolutely not. Let me give you an
example.
Let’s assume you release the first version of your application as a paid
application. After a few months, you realize it isn’t doing as well as it
could. You want to make the application free with an in-app purchase to
unlock premium content.
You could simply implement the in-app purchase, but this would anger
customers that purchased your application when it was paid up front. The

solution is simple, but it requires some work. The App Store receipt
includes the original purchase date. Your application can inspect the
receipt and only offer the in-app purchase to customers that downloaded
the application after you made the switch from paid to free with an in-app
purchase.

Evolution
The mobile space continues to evolve and that also means that you and
your business need to evolve. This doesn’t need to be scary, but you
need to be vigilant. Keep an eye on the industry. Which trends are
emerging? What’s working for other developers? Talk to your customers?
What are their expectations? You may be surprised by their responses.

PART 8: YOU

1 Being and Staying Productive
Productivity is a topic that many people have written about and I’m
certainly not a guru when it comes to productivity. Through trial and error,
I’ve learned what works and what doesn’t.
Productivity is a very personal subject. What works for me may not work
for you. For that reason, I won’t be bombarding you with tips and tricks in
this chapter. Instead, I cover a few key elements that directly and
indirectly impact your productivity.

Maintaining Focus
One of the biggest challenges we’re faced with as developers is
maintaining focus throughout the day. The people we work with often
expect us to be available at all times. If you cannot cope with that feeling,
it can add a substantial amount stress to your life.
That’s why it’s vital to set boundaries. This is even more true for
freelancers and consultants. If you run a business, people seem to
expect you’re working every waking moment. You are the business and
you should always be available.
Don’t make that mistake. Set boundaries for yourself and for the people
you work with. Believe me. People will respect you for it. And those that
don’t may not be the people you should be working with.

Protect Your Productivity
Open offices are very popular in the technology industry. While I
understand their appeal, I’m not a fan. It’s true that they promote
communication and collaboration, but they’re almost always destroyers of
productivity. Because your desk isn’t surrounded by four walls, people
tend to think that they can step into your imaginary office whenever they
feel like.

As a developer, you need focus and you need to know that people won’t
disturb you when you’re writing code. Most of us know this, which is why
open offices are usually filled with people wearing headphones. The
headphones are a silent protest against the lack of an office or a space
that allows people to focus on what they’re supposed to do.
Make it clear to the people you work with that they can’t or shouldn’t
disturb you whenever they like. Isn’t that what the daily scrum meetings
are for?

Distraction Is Addictive
As if open offices aren’t enough, instant messaging, like Slack, are used
in almost every technology company. They’re incredibly useful and, at the
same time, a major distraction for most developers. The same is true for
instant messaging of all forms and shapes.
Being distracted has become an addiction for some of us. We get a kick
every time we see an email come in, a message on Slack, or a new tweet
on Twitter.
For many of us, it’s a problem, a real one. We’re being distracted and
we’re craving for distraction. I don’t have the perfect cure to battle
distraction, but I have a piece of paper taped to the wall opposite my
desk with three lines of text.
Have Focus, Remove Noise, Set Boundaries

Have Focus
This is a very effective strategy if you stick to it. The first line is simple.
Make sure that you know what you’re doing. Your focus should be
singular. This may sound obvious, but many of us start to procrastinate
and look for a distraction when we don’t have a clear focus. Every time I
don’t have a clear focus I ask myself a simple question.
What’s the next action I need to take to move forward?

I believe I read this in a book by David Allen years ago. It’s a powerful
technique to get unstuck and move on. It works very, very well if you’re
battling a complex programming problem, because, let’s be honest, even
complex problems and solutions can be broken down into simple,
manageable pieces.
If you’re having a rough day, I recommend taking tiny steps. Launch
Xcode. Open the project you’re working on.

Remove Noise
Focus is only possible if you remove anything that can distract you. Set a
timer for 30 to 60 minutes and remove every possible source of
distraction. I’m writing this on a laptop without an internet connection in a
dimmed room on an improvised standing desk. I have notifications
disabled, closed browser windows, and I can only be disturbed by
emergencies.
Is this overkill? I don’t think so. How do you think programmers got work
done twenty or thirty years ago? They weren’t distracted by Slack, mobile
phones, and a constant influx of news, tweets, and messages. We
haven’t evolved since those days, which means we are not immune to
the distractions of today’s world.
I have one pro tip for you. If you’re working on an iOS application, make
sure you use a test device, not your personal device. It makes it easier to
block out messages, phone calls, and other distractions that your phone
receives.

Set Boundaries
This is a big one. A few months ago, I read an article on productivity by
Ramit Sethi. In the comments of the article, a reader asked Ramit about
being overwhelmed by work and the feeling that everything was getting
too much. Ramit responded to this person’s comment and pointed out
that overwhelm is almost always caused by a lack of boundaries.
I wrote about setting boundaries earlier in this chapter. Not setting
boundaries can mentally and physically exhaust you. How do you set
boundaries? Turn off your computer at 6PM and make it a habit that you

don’t check email or messages from work after that time. That’s a good
start.
This can be challenging if you’re not used to do this, but after a few days
you should feel more relaxed and more energized the next day. A spring
that’s constantly stressed loses its flexibility and the same happens to
people. The result can be burnout or depression, both of which are
difficult to recover from. This brings me to the last section of this chapter.

Take Care of Yourself
A runner running a marathon doesn’t run all out for the entire race. She
keeps something in the tank for the finale of the race. Working as a
developer is similar. Make sure you don’t push yourself to your limits day
in day out. Make sure you have a healthy reserve for when it gets tough
or when things hit the fan.
You’re in it for the long run and that means that you need to take care of
yourself, including your body. I’m in my thirties and burning the midnight
oil is something I can no longer pull off without suffering the
consequences. I see young people drinking energy drinks and
bucketloads of coffee. This isn’t healthy and you will pay the price at
some point. You probably won’t believe me if you’re in your twenties.

2 Stop Looking for the Silver Bullet
Most frameworks and libraries have guidelines and best practices.
Apple’s SDKs are no different. While there’s room for experimentation
and exploration, a typical iOS application, for example, uses one or more
view controllers and the user can navigate between those view
controllers. That’s a recipe you’re probably familiar with.
Not every problem you face during development has one solution,
though. This is a common issue developers face when they use Core
Data, for example. They run into an issue and they try to resolve it by
looking for the recipe that fixes their problem.

An Example
A few years ago, Florian Kugler wrote an excellent article in which he
compares three Core Data stack configurations. In his article, Florian
tests how each Core Data stack performs when the application imports a
large data set in the background. The results were surprising, to say the
least.
The Core Data stack Apple and several known experts recommend
performed terribly. I was surprised by the results and so was Florian. He
investigates the test results and unravels why a Core Data stack with a
parent-child configuration doesn’t handle large background imports very
well. It’s a very good read if you’re interested in Core Data performance.
To resolve the issue, Florian didn’t go looking for the silver bullet in the
Core Data programming guide because there is no silver bullet. There
are best practices and guidelines, but not every problem can be solved
with a clear-cut recipe.

Investigate and Test
A few months ago, I came across an article by Sam Soffes about
improving application performance with the help of Instruments, one of

the most underused developer tools for Cocoa development. In his
article, Sam describes how he spent an afternoon investigating three
performance issues in an application he was working on.
As with many performance issues, the bottlenecks were unexpected.
One issue, for example, was caused by a date parser that parsed ISO
8601 dates. He only discovered this issue by profiling the application’s
performance.
Sam tested, investigated, and improved the application’s code base. He
didn’t follow a recipe and he certainly didn’t search for a silver bullet to
solve his performance problems.

Stop Looking for the Silver Bullet
If you’re new to a framework or library, it can be frustrating or even scary
to know that you’re on your own to fix performance issues or other issues
that are specific to your application. But that’s the reality of software
development.
It’s true that you may be using the framework or library incorrectly. That’s
actually a common cause of bugs and performance problems. The
moment your project gains in complexity, you’re often on your own. You
can learn from other developers that have faced similar issues, but it’s
important to stop looking for the silver bullet that you may think you can
find somewhere.
Instead, profile your application, investigate the results, and try to
improve performance problems or fix that hard to find memory leak.
That’s how you grow as a developer. Being afraid of exploring uncharted
waters is understandable, but that doesn’t mean you shouldn’t give it a
try.

3 You Are Not an Imposter
Have you ever heard of imposter syndrome? Like Pauline Rose Clance, I
prefer imposter experience as it better describes the problem.
A surprising number of people suffer from imposter experience. And
developers are no exception. What is imposter experience? And why am
I writing about it in this book?

What Is It
People suffering from imposter experience are generally very good at
what they do. They’re often perfectionists, giving their very best. Yet they
feel insecure and, at times, they think of themselves as frauds or
imposters. They feel as if they’re tricking the world into believing that
they’re better than they actually are. Does that sound familiar?
If you want to learn more about imposter experience, I recommend
reading the Wikipedia entry on the topic. It does a great job at explaining
the details.

Why Do I Bring This Up
Regular readers of Cocoacasts know that I occasionally write about the
psychological aspects of being a developer, working as a freelancer, or
running a business. These are topics I have a special interest in since
they’re an integral part of being a developer.
Topics like imposter syndrome or experience are often ignored, discarded
with a laugh, or trivialized. But if you’re a developer and you want to live a
happy life, enjoying the work you do isn’t enough. It’s equally important to
feel comfortable around the people you work with and the environment
you spend a good chunk of your time in.

Curing Imposter Experience

It’s important to emphasize that I’m not a psychologist and have no
medical training whatsoever. The advice I offer is based on my own
experience and conversations with developers like yourself.

Honesty
Imposter experience is pretty common among freelance developers,
especially if you’re working in a team of one. Why would anyone pay you
money for the code you write? And what if people find out that you’re not
as good as they thought you were?
One of the best cures for imposter experience is honesty and openness.
When Swift was introduced in 2014, apart from a handful of developers at
Apple, nobody knew what Swift was. Best practices were still waiting to
be discovered and everyone played with and explored the language.
Natasha Murashev has been a true inspiration for many developers.
From the start, Natasha has openly documented her exploration of the
language, sharing her discoveries along the way. Even though she’s a
fantastic developer, she doesn’t proclaim to be an expert. Especially in
the early days of Swift, her blog read like a diary of how she explored the
language. She studied Swift honestly and openly, the perfect remedy to
cure and even prevent imposter experience. It makes Natasha’s blog fun
to read and it immediately creates a human connection.

Don’t Make Promises You Can’t Keep
Years and years ago, I taught students at a university in Belgium. One of
the key lessons I learned from one of my mentors was to be up front with
your students about what you know and, more importantly, what you
don’t know. If a student asks you a question you don’t know the answer
to, tell them.
Admitting that you don’t know something makes you human. You’re not a
robot and your brain isn’t plugged into Google—not yet anyway. But
there’s more. Most people show respect if you can admit that you don’t
know or cannot do something. What can seem like a sign of weakness is
actually a sign of strength and confidence.

It Automatically Disappears

I don’t feel it’s important to understand the root cause of imposter
experience to rid yourself of it. After a while, it disappears automatically.
Whenever I discuss a project with a client, I’m open and honest about
what’s possible and what isn’t. If I’m not familiar with a specific
technology, I tell them and provide an alternative.
Being open increases your credibility and it strengthens the relationship
with the client. It’s a powerful antidote for imposter experience.

Talk About It
I’ve been wanting to write this post for quite a while. What inspired me to
take action was a recent episode of the Tropical MBA podcast,
TMBA384: Are You an Imposter?. One of the key takeaways from the
episode is simple, surround yourself with like-minded people and talk
about it.
You only feel like an imposter if you compare yourself with others. —
Luis Miguel Gil
Dan interviews several people that openly talk about imposter
experience. Luis Miguel Gil opens up about how he experienced imposter
experience. He also zooms in on what causes imposter experience and
how to defuse it. This is what Luis has to say about feeling like an
imposter.
When I compare myself with Luis from three years ago I see huge
growth, huge success. Amazing. I’m very happy and very proud of
what I’ve accomplished. But when I compare myself with people like
you guys (Dan and Ian, the hosts of the podcast) or other
entrepreneurs that have had many amazing successes, I feel I’m far
away from reaching that. I’m so far away. — Luis Miguel Gil
It can sometimes be easy to become overwhelmed or intimidated by what
others are doing and have achieved, especially if you watch too many
talks or read too many blog posts. It’s important to appreciate yourself
and don’t undervalue what you’ve already achieved.

It’s Common
Imposter experience isn’t uncommon. Many people suffer from imposter
experience, including people that are considered top performers in their
field. Tom Hanks, one of my favorite actors, made a surprising comment
several years ago.
I still feel sometimes that I’d like to be as good as so-and-so actor. I
see some other actors’ work, and I think I’ll never get there. I wish I
could. — The New York Times
This may seem odd for someone who’s won two academy awards. It
shows that it isn’t uncommon. It makes him human and approachable.

Don’t Believe Everything You Read
Imposter experience can also be fueled by believing everything you read.
Some people may claim that they built a successful business in two
months by working five hours a week. That may be possible, but they’re
the exception to the rule.
Don’t compare yourself with exceptions. If you want to achieve something
that you’re proud of, you need to put in the work. If you want to become a
great developer, you’ll need to write code, and lots of it. And spending
your days reading tutorials or browsing Stack Overflow won’t help much.

Don’t Let It Affect You
Most developers suffer from imposter experience at some point in their
life. And that’s fine. It won’t kill you. But Dan Andrews emphasizes that
impostor experience can grow into a problem if, how you run your
business or your career, is affected by imposter experience.
This is a problem I see many freelancers struggle with. They undervalue
what they have to offer. Something that seems easy or even trivial to you
can be of great value to others. That doesn’t mean you need to
undervalue yourself or, heaven forbid, do it for free. The reason you find it
easy is because you’re an expert at what you do. And that’s why people
want to pay you for your services and expertise.

A carpenter gets better the longer he does his job. This means he gets
better the older he gets. Do you think he drops his hourly rate as he gets
better and grows older? The opposite is true. Don’t think for a second
that you’re any different.

Success Through Failure
Failure continues to be a touchy subject in many parts of the world. I feel
it’s much less of a taboo in the United States. Let’s be honest, if you
succeed without failure, then you haven’t aimed high enough.
Every single person that has reached success has experienced failure.
It’s not something to be embarrassed about. You can only succeed by
trying, failing, trying harder, failing again, and persisting until you
succeed.
Remember this, if you succeed without failing, you’re not aiming high
enough. Be realistic, but make sure you’re not underestimating what you
can achieve. Some things are hard, but that doesn’t mean they’re
impossible.

PART 9: LEARNING

1 Choose Your Teacher Wisely
The vast number of tutorials and courses about software development is
a blessing for anyone interested in building software. And this is no less
true for anyone interested in Swift development. Getting started with Swift
development is easy and it doesn’t need to cost you a fortune. But, as
you’ve probably discovered, there’s a downside to this wealth of
information. In this chapter, I’d like to highlight three problems that I
frequently face and hear about from my students and readers.

Information Overload
When I started learning Cocoa development in 2006, there were only a
handful of books available. Aaron Hillegass’ book Cocoa Programming
for (Mac) OS X was the unofficial golden standard.

Cocoa Programming for (Mac) OS X

But, with the introduction of the iPhone in 2007 and the release of the
official SDK in 2008, that number increased substantially. There are
many books available from traditional publishers, such as Apress and
O’Reilly, but many developers, including yours truly, have chosen the
path of self-publishing, bypassing traditional publishers.
It has never been easier to publish a book or course. Books and courses
are available at any price point, including free. Unfortunately, this has
made it more challenging for developers to decide which path to choose
to learn the topic they’re interested in. Each day new tutorials, videos,
and courses are published. It’s challenging. That’s for sure.
The blessing of having so much free information at your fingertips is more
often than not a curse for developers that want to learn Cocoa and Swift
development. Not only is the amount of information overwhelming, there
doesn’t seem to be a clear path to follow. It’s difficult to see the forest for
the trees. Don’t stop here, though. There’s hope.

Who to Trust
Every developer that writes about Cocoa and Swift development does
this with the best of intentions. They want to help people learn something
new or solve a problem they’re having. It’s fantastic to see how many of
us take the time to write a tutorial or produce a video to help others. It’s
one of the key ingredients of the thriving Cocoa and Swift communities.
Despite the author’s good intentions, though, what they’re teaching may
be incorrect or ignore good practices. If you’re new to a subject, then you
may not be able to spot these mistakes. The title of this chapter is very
telling. It’s become more important than ever to choose your teacher
wisely. While I don’t believe that people are intentionally putting out bad
content or incorrect information, it’s up to you, the student, to filter the
good from the bad.
A few weeks ago, I was looking for a solution to customize the color of
the clear button of a UITextField instance. It turns out that the tint color of
a UITextField doesn’t affect the clear button. Bummer. I was having an
issue where the clear button was nearly invisible against a dark
background.

During my search for an answer, I stumbled on several Stack Overflow
entries that recommended digging into the view hierarchy of the text field,
looking for the clear button, and modifying its tint color. As I mention
elsewhere in this book, this is a bad practice. If the API doesn’t allow for
this type of customization, you file a bug with Apple and implement a
custom solution. That’s the only correct solution. Your clever workaround
will inevitably break when Apple makes changes to the internals of the
UITextField class. Respect the SDK. Always.
The answers that suggested digging into the view hierarchy of the text
field were upvoted because, at that time, it solved the problem.
Unfortunately, this creates a bigger problem. Every inexperienced
developer that reads one of these answers is made to believe that this is
a viable solution, that this is fine. Instead of spotting the risk of the
solution, they wrongly believe that they’ve picked up a good practice they
can adopt in other, similar situations.
If I need to pick up a new framework or API, I rely on the people I have
come to trust over time. These are very often people that have built up
authority in the community over several years or people like Aaron
Hillegass, Marcus Zarra, and Jeff LaMarche that have been around since
the very early days of the platform.

Focus, Focus, Focus
I used to follow a slew of developers on social media. I wanted to know
what they were learning, what they had to share, and which techniques
and lessons I could adopt in my own projects. About a year ago, I
stopped doing this because it was too overwhelming. There’s so much to
learn. The platforms and the Swift language evolve so quickly that it’s
hard to keep your focus if you don’t protect it ferociously.
There are countless talks about almost any topic you can imagine, but it
can leave you with more questions than you started with. I don’t know
about you, but focus has been the cure for me. Attention has become so
important in today’s busy world that having the skill to focus obsessively
is a skill every developer should learn to master.
I don’t believe in the concept of a genius. It’s true that some people are
more gifted than others, but, in the end, developers that excel in what

they do are those who can focus and commit to something. You don’t
master Swift by reading a few chapters in Apple’s language guide. That’s
a good start, but it’s a process that continues and never stops. That’s the
beauty of it. No? Didn’t you become a developer because the sky’s the
limit?
That’s also why I often ask developers what goals they have for the
coming months or years. What I’m actually asking them is what their
focus is. What are they trying to accomplish? Ambitious people have a
clear focus, very often a singular one. Let me ask you then, “What is your
focus?”

Never Stop Learning
The mobile space is still very young, relatively speaking, and it evolves at
an incredible pace. With Apple and Google heavily investing in their
platforms, the speed with which mobile platforms evolve requires
developers to focus and learn non-stop.
In 2015, Apple introduced no less than two new platforms, tvOS and
watchOS. While developers familiar with iOS won’t have a hard time
getting up to speed with Apple’s brand new SDKs, there are many, many
APIs and paradigms to become familiar with. It’s understandable if you
feel a little overwhelmed as a mobile developer. That’s fine and it’s fine to
admit that.
If you decide to become a developer, regardless of the platform you write
software for, you need to accept and become comfortable with the fact
that learning on a daily basis is part of the job.
For the past few years, Apple has released a new version of its operating
systems every year, introducing new technologies we need to become
familiar with. The Swift project continues to evolve at a fast pace. At the
time of writing, Swift 4 is just around the corner and with it come new
features, bug fixes, and numerous improvements.
Are you ready to dive in head first? If Apple announces a slew of new
APIs next year, will that scare you or will it excite you? Do you have the
motivation to not only continue learning but also push the envelope.

Using an API is one thing, pushing it to its boundaries and beyond is
where it’s at.
If you like programming, but prefer to stick with what you know, then
mobile development may not be the best choice. If learning is in your
blood and the mere thought of WWDC or Google I/O gives you
goosebumps, then being a mobile developer is the best job in the world.

2 Taking a Shortcut
What I like about programming and software development is that
everyone is treated the same. This means that there are no shortcuts you
can take. This is something I bring up several times in this book because
I strongly believe that you need to put in the work if you want to evolve
into a proficient Swift developer.
If your goal is to become one of the world’s top violinists, then you simply
need to put in the hours. The same applies to programming and software
development. Why would it be any different?
Even though there are no shortcuts, there are several paths you can take
to speed up your career. The shortcuts I mention in this chapter are
legitimate recipes to accelerate your growth as a developer.

Internship
An internship at the right company can speed up your career
dramatically. Why is that? A junior developer has a lot to learn and that’s
something many, many developers are overwhelmed by. What do I need
to learn next? What do I need to know to build my first application?
There’s a lot to learn and a lot that you could learn. Which topic is the
next step you need to take. Having a mentor or a senior developer by
your side can make a world of difference. For this to work, though, it’s
important that you carefully choose the place you apply for an internship.
It’s fine to be picky. It’s not because you have little experience that you
have to accept what you can get. Do your research, ask around, and
contact the companies that you think are a good fit for you and what you
want to achieve.

Freelancing and Subcontracting
The life of a freelancer may seem like the perfect life to many developers.
It’s true that it comes with several perks. You can start work whenever

you like and you can choose your workplace. But it’s a tough life at times,
especially if you’re just starting out.
For that exact reason, however, freelancing can be a shortcut in your
career. You’re forced to learn a lot of stuff and figure things out on your
own. You need to take care of a million things to keep your business
afloat. You need to develop skills you didn’t know you ever needed, such
as writing proposals, talking to clients, and working with subcontractors.
This isn’t for everyone, but if this sounds like a challenge to you, then
freelancing can significantly speed up your career.
Subcontracting is similar to freelancing. The difference is that you usually
work at your client’s company. It can sometimes feel as if you’re an
employee if you’re subcontracting. The reason I consider subcontracting
a shortcut is for exactly that reason.
As a subcontractor, you usually become a member of the team at the
company you work for. You learn about the company’s culture, the tools
they use, their workflow, and their automation. The result is that you learn
a lot in a short amount of time. You see what works and what doesn’t.
I worked as a subcontractor for several years and it has taught me a lot
about the various aspects of running a business, project management,
programing, automation, and testing. The bigger the company, the more
effective this shortcut is.
As a subcontractor, you switch companies from time to time and that only
increases the amount you learn. Every company does things differently
and that’s what you’re looking for. You can pick and choose what works
and apply that. It’s one thing reading about something, but it’s something
completely different to be immersed in it.
If you’re a freelancer and freedom is important to you, then
subcontracting may not be what you’re looking for. Keep that in mind
when you’re given this opportunity.

Learn, Learn, Learn

If you’re reading this book, then it probably means that you’ve chosen for
a career in the mobile space or you want to build fantastic products that
help thousands or millions of people. The technology industry is evolving
at a breakneck pace and you need to stay up to date. You need to learn
every single day.
That doesn’t necessarily mean that you need to spend an hour a day with
your nose in a book. It’s enough to have an open mind. What does that
mean? Over the years, I’ve developed a slew of habits and strategies to
solve common programming problems. But I try to do things a bit
differently every time I work on a project. That’s how I discovered the
Model-View-ViewModel pattern. The view controllers in my projects were
getting too heavy and it was time for something different.
I studied the pattern for several weeks, tried a few implementations, and
settled with a solution I satisfied my needs and requirements. That’s how
I usually pick up new frameworks and libraries. Have an open mind and
try to do thins a bit differently every time you encounter a familiar
problem.

Build, Build, Build
One of the main reasons I continue to invest time and energy in side
projects is to learn and experiment. If you’re working for a large agency
or a product company, you don’t necessarily have the luxury of working
with the latest and greatest. Many companies postponed the transition to
Swift for the first few years because Objective-C was much more reliable
and it had a proven track record. But what’s stopping you from learning
Swift today? What’s stopping you from playing with Core Data or Realm
in your spare time?
If you’re lucky, then you work at a company that gives you the freedom to
learn new things on the job. While this may seem like a generous
gesture, your employer knows and understands that they need to invest
in their employees and their education. The technology industry is a
competitive arena and what worked yesterday may no longer work today
or tomorrow.

Choose Wisely

I started this book with a strong focus on your foundation and I want to
briefly revisit this topic. It’s tempting to focus on the shiny stuff companies
like Apple and Google spoil us with. But remember that you make a living
building applications that are powered by technologies that have been
around for decades. Make sure you don’t neglect your foundation.
With a solid foundation it’s easier to pick up new technologies. Once you
understand how the puzzle fits together, it’s easier to pick up new
languages, frameworks, and libraries. Investing in your foundation should
always be your main concern. It helps you build confidence and it
ensures that you can make a living doing what you love doing, building
software.

3 Some Things Are Hard
Before the iPhone was introduced in 2007, Cocoa Programming for Mac
OS X by Aaron Hillegass was the book if you were interested in Cocoa
development. It was Aaron’s book that introduced me to Cocoa
programming.
One of the most important lessons Aaron taught me had nothing to do
with programming. In the first chapter of his book, Aaron writes about
Rock, a former boss he had worked with.
I used to have a boss named Rock. Rock had earned a degree in
astrophysics from Call Tech and had never had a job in which he
used his knowledge of the heavens. Once I asked him whether he
regretted getting the degree. “Actually, my degree in astrophysics
has proved to be very valuable,” he said. “Some things in this world
are just hard. When I am struggling with something, I sometimes
think ‘Damn, this is hard for me. I wonder if I am stupid,’ and then I
remember that I have a degree in astrophysics from Cal Tech; I must
not be stupid.” - Aaron Hillegass
Some things are hard. Unfortunately, admitting that some things are hard
is some sort of taboo among programmers. You lose credibility as a
programmer if you admit that you’re struggling understanding something.

Cut Yourself Some Slack
If you’re just starting out as a programmer or you’ve been developing for
years and are now testing the waters with a new language or technology,
then cut yourself some slack if you’re not making as much progress as
you’d hoped. Some things are hard and that’s fine.
Generics, for example, are mischievous creatures if you’re coming from
C or Objective-C. It’s fine if you need a bit more time to let this paradigm
sink in. Currying is a concept even some experienced developers avoid

because it isn’t easy to grasp if you’re not used to functional
programming concepts.
That’s fine. Unless you’re a genius, you will struggle at times. That’s what
makes programming fun. Right? What would the challenge be if every
day was a walk in the park. Why would you invest time and energy in
learning something if it was easy.
It’s not that I’m so smart, it’s just that I stay with problems longer. —
Albert Einstein
Programming is about solving problems and that includes learning a new
language, framework, or technology. Challenging yourself is important,
but it’s equally important to give yourself a break from time to time.
Some things are hard and that’s fine.

4 Learn the Rules, Then Break Them
When you’re starting out as a developer or you’re learning a new
language, framework, or library, you’re often wondering what the best
practices are and which rules you need to stick to. Most of us have gone
through this phase when we learned the Swift language.
I often bring up Core Data because it’s such a good example. Developers
are very often frustrated with the framework and that’s in part why the
framework doesn’t have a great reputation. I can assure you that the vast
majority of problems is caused by not knowing about or ignoring the rules
of the framework.

Examples
Views are supposed be dumb. A view should only know how to present
the data it’s given. This is a rule you shouldn’t break. But I don’t agree
with that. Once you understand why this rule is important, it’s fine to
break it as long as you understand what the consequences are.
I sometimes break this rule when I create a complex table or collection
view. If you notice that you’re making it very hard on yourself to keep the
view dumb and ignorant, then it may be better to look for an alternative.
In such a scenario, I promote the table or collection view cell to a
controller. I see each table or collection view cell as a view controller and
its content view as the view controller’s view. This can often reduce the
complexity in the view controller that drives the table or collection view.
I know that I’m breaking a rule and I understand the impact of that
decision. That understanding gives me the confidence I need to
implement a solution I know works better.
Another common example involves the Model-View-ViewModel pattern.
You may have read that importing UIKit in the view model is a code
smell. I agree with this statement and understand why that is. The view
model shouldn’t know about the view it powers through the view

controller. If you import the UIKit framework, it indicates that you’re doing
something in the view model that relates to the view layer hence the code
smell.
This is clear. But I sometimes break this rule for obvious reasons. What if
I want to return a UIImage instance from the view model or I want to
specify the accessory type of a table view cell? The second example is
harder to justify, but returning a UIImage instance is a fine example. The
UIImage class is defined in the UIKit framework and if you want to return a
UIImage instance, you have no other option but to import the UIKit
framework. You could stick to the rules by just returning the name for the
image, but is that really a better solution? Isn’t that simply a workaround
to abide by a rule?

Growing as a Developer
There’s a subtle but important difference between violating a rule and
breaking a rule. Breaking a rule implies that you know about the rule and
you should know about the consequences. That said, break rules
sparingly. There’s a reason why design patterns and best practices exist.
It can sometimes help to play by the rules to understand how to break
them.
There’s a subtle but important difference between violating a rule
and breaking a rule. Breaking a rule implies that you know about the
rule and you should know about the consequences.
If you’re new to a language or framework, then I recommend playing by
the rules. This is essential to understand the language or framework,
learn about the API, and how the various pieces of the puzzle fit together.
You cannot safely break a rule if you don’t know what the consequences
are. Junior developers do this frequently without realizing it. And that’s
fine. You always learn something if you make a mistake. Just make sure
you don’t make the same mistake twice.

Creating Something Better
The concept of breaking rules is quite common in design. Revolutionary
designs don’t emerge by sticking to the rules. Even though this is less

obvious in software development, breaking rules can lead to better
design patterns or practices. But it requires a deep understanding of
those rules to pull it off.



Source Exif Data:
File Type                       : PDF
File Type Extension             : pdf
MIME Type                       : application/pdf
PDF Version                     : 1.4
Linearized                      : No
Author                          : Bart Jacobs
Create Date                     : 2017:09:29 13:52:50+00:00
Producer                        : calibre 3.7.0 [https://calibre-ebook.com]
Title                           : The Missing Manual for Swift Development
Description                     : 
Creator                         : Bart Jacobs
Publisher                       : leanpub.com
Subject                         : 
Date                            : 2017:09:26 00:00:00+00:00
Language                        : en
Identifier Scheme               : mobi-asin
Identifier                      : B075Z7ZTMJ
Metadata Date                   : 2017:09:29 13:52:50.920121+00:00
Timestamp                       : 2017:09:29 13:52:34.839890+00:00
Author sort                     : Jacobs, Bart
Page Count                      : 269
EXIF Metadata provided by EXIF.tools

Navigation menu