Introduction
The aim of this post is to demonstrate how it is possible to do continuous delivery for iOS. This post contains an example application written in Swift and uses automated tests to drive the development.
We will start from the very beginning, how to bootstrap a new swift project in Xcode and setup a dependency manager.
Then it will be shown how to write unit test and UI tests for an iOS application.
We will finish by showing how it is possible to setup a continuous integration system using an external service, and how to use this service to deploy our application directly to our users.
The project example is at https://github.com/tiagomartinho/StringCalculatorSwift
Project Bootstrap
NOTE: This post was done using Xcode 7.0.1 and Swift 2.0.
Create a New Project
Creating a new iOS project is as simple as opening Xcode and, using the new project assistant, select the single view application template.
Then select the language as Swift and the option to include the unit tests and UI tests, since they will be useful later on.
This creates our project and three targets, one for the application, one for the unit tests, and one for the functional tests.
If you didn’t select the option to include the tests target in the creation of the project (or you already have a existing project) you could add the tests by adding a new target to the project and select the following templates.
Setup the Dependency Manager
The dependency manager used in this example is Cocoapods, as from https://cocoapods.org:
“CocoaPods is the dependency manager for Swift and Objective-C Cocoa projects. It has over ten thousand libraries and can help you scale your projects elegantly.”
Setting right away cocoapods gives us the flexibility for later adding external dependencies easily.
To setup cocoapods first is needed to install it (if you don't have it already) by running the command:
> sudo gem install cocoapods
Then it is needed to define a pod file (a simple text file containing all the dependencies of the project)
Here is an example Podfile:
platform :ios, '8.0' use_frameworks! target 'MyApp' do pod 'AFNetworking', '~> 2.5' pod 'ORStackView', '~> 2.0' pod 'SwiftyJSON', '~> 2.1' end
You'll need to run the following command to install the dependencies:
> pod install
From now on we have to work with the workspace instead of the project as before.
All dependencies can be easily used using import statements in our swift files.
import AFNetworking
Writing Our Application
To write our application we will use TDD and to do so we need a way to write and run unit tests efficiently.
Our example application will be an iOS application of the string calculator kata. As seen in https://osherove.com/tdd-kata-1/
Unit Tests
To unit test our application we will use XCTest the Xcode Testing Framework.
To define a new unit test class we use the new file template of Xcode and select Unit Test Case Class.
One important thing is to add all the classes under test not only to the application target but also to our test target, otherwise the tests cannot see the classes under test.
Another way is to use the new @testable annotation like that:
@testable import targetOfTheApplication
As seen in https://natashatherobot.com/swift-2-xcode-7-unit-testing-access/
Now we can write our first test:
To run all the tests of the application press: CMD + U
To run all test of the selected test class press: CTRL + OPTION + CMD + U
To run the previous tests press: CTRL + OPTION + CMD + G
From here we can write our String Calculator class using TDD. If you want to follow all the history of the development take a look at the git log https://github.com/tiagomartinho/StringCalculatorSwift/commits/master
UI Tests
To test that our application features work as expected we will use the same Xcode Testing Framework, XCTest.
To define a new UI test class we use the new file template of Xcode and select UI Test Case Class.
And add it to our UI test target.
I like to modify the template of Xcode by extracting the application variable and removing the unused methods and comments:
To write our first UI test first we have to define the accessibility identifier of our UI in order for them to be accessible by the framework.
This can be done programmatically by code or by setting the property on the storyboard.
If the UI element does not have the property accessible from the storyboard it is possible to defined it as a user defined runtime attribute.
After setting the accessibility identifier for the elements of our UI, we are now able to write our UI tests.
To get a reference to the UI element we define a variable as an XCUIElement and based on the type we reference it by doing:
The first test is to assert that all elements of the UI exist and have the correct initial state:

In the second test we insert text into a text field object and press the calculate button. We then assert that all labels contain the correct text.
The purpose of this UI tests are not to assert the logic of our app, since we already tested it in the unit test, but to test if the UI behave according to our expectations and if all elements are accessible.
Continuous Integration and Continuous Delivery for iOS
To implement the continuous integration of our app we will use an external service called Greenhouse CI.
The first step is to set the repository where the project is hosted:
Then all the project information to build the project:
Greenhouse has a great troubleshoot guide in case you are not able to import correctly the provisioning profiles and certificates.
You can also set the environment using variables or specific files for your scripts, and choose the version of Xcode to use.
To deploy your application to your users you can configure the tab Publish. In this example we use Beta by Crashlytics (Fabric). You get the API key and Build secret from https://www.crashlytics.com/login?redirect_url=%2Fsettings%2Forganizations if you already have an account from Crashlytics.
From here you can save the configuration and hit Build.
After the build finishes you will see in the Fabric website the build available.
And your testers you receive the following email to test the application.
Conclusion
In this post we saw how it is possible to do continuous delivery of an iOS application. Starting from the creation of the project to writing our first unit and UI test, till the automatic deploy to our testers.
The sample project is available at https://github.com/tiagomartinho/StringCalculatorSwift
















