Hide chapters

iOS App Distribution & Best Practices

First Edition - Early Access 1 · iOS 14.2 · Swift 5.3 · Xcode 12.2

Before You Begin

Section 0: 3 chapters
Show chapters Hide chapters

Section I: iOS App Distribution & Best Practices

Section 1: 17 chapters
Show chapters Hide chapters

13. Build Automation
Written by Keegan Rush

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

The world of computing has come a long way in the last century.

The ancient predecessor to a modern computer is an abacus, used to add numbers. This became the inspiration for more sophisticated adding machines, and then calculating machines that could add, subtract, multiply and divide. But, until the twentieth century, computer programming was a non-existent profession.

In 1936, the first programmable computer was invented, and soon the modern age of computing was underway. In the early days, programmers had to work directly with machine code that was unique to each type of computer. It wasn’t until the invention of assembly language that programmers could worry less about the intricacies of ones and zeros and focus more on the software they were writing.

Eventually, the industry took another leap forward with the invention of FORTRAN in the 1950s, the first high-level programming language. With each step to higher level, more abstract programming languages, a programmer has to worry less about how to write the code and more about the problems they’re trying to solve. The journey towards higher-level programming languages continues even today, with you writing Swift in Xcode’s cushy interface.

Before the adoption of integrated development environments (IDEs) like Xcode, programming was done in text editors, and before that, on the command line. Without an IDE, you have to invoke compilers from the command line to build apps.

Using Xcode means you get to worry less about the technical details and more about making an app that people will love. But, sometimes, you have to take a step back to take another gigantic leap forward.

In this chapter, you’ll step outside of Xcode and learn how to leverage the command line to build your apps. You’ll automate Emitron by creating a simple build script that does the following:

  1. Builds and archives Emitron.
  2. Exports the archive into an .ipa.
  3. Uploads the exported archive to App Store Connect.

In doing so, you’ll learn how you can automate the distribution process.

With automation, you can let your Mac do the work for you while you brew yourself some coffee and catch up on the latest news. :]

Note: This chapter requires some basic knowledge of the command line.

Also, if you’re already sold on the benefits of automation, feel free to skip to the next chapter. There, you’ll learn how to use fastlane, a powerful tool for automating builds and more.

Why automation

Imagine the following manual release process:

You need to release a new build of your app to the App Store. The code is ready, but you need to build the app for distribution using Xcode’s Product ▸ Archive menu option. Then, you sign the archive for App Store distribution and upload it to App Store Connect.

On App Store Connect, you have to add in all the metadata for your release: your app categories, copyright info, marketing copy, review information and more.

Next up is one of the most tedious parts of releasing an app: the screenshots. You’ll need to go back to Xcode, run your app in a handful of different simulators to take a handful of different screenshots. If your app is localized into other languages, don’t forget to take screenshots for those languages, too.

Once you’ve added your metadata and screenshots, you’re ready to submit your app for review.

From build to App Store

Now, consider the alternative automatic release process.

Other benefits of automation

Besides the automation script handling all the steps from build to App Store, there’s a myriad of other benefits to automating your build. This includes:

Validation by testing

The benefits of automated testing are well known, but that doesn’t mean developers remember to run tests before every release build. By including tests in an automated build, you have the assurance that everything works as expected. Any failing tests will stop the build to let you catch bugs before they hit the App Store.


Leaving release builds as a manual process opens it up to human errors if you don’t pay enough attention. You could forget to run your automated tests, or compile the app with the wrong build configuration or provisioning profile. Or even worse, you might end up mistakenly releasing a feature that you haven’t finished yet!

Shared knowledge

Have you ever taken over development of an old app that someone else built?

Frequent builds

Because it’s so easy to release new builds when you’ve automated the process, builds can come more frequently. The lower barrier to building means getting your latest work into the hands of testers and the general public much sooner.

Continuous integration

The pinnacle of frequent builds, continuous integration lets you build and deploy your app as soon as you push your changes to GitHub. You don’t even have to run the automation script yourself.

Setting up the starter project

Before you create a build script for Emitron, you’ll need to configure the project for your Apple Developer account.

Building with xcodebuild

You’re not far away from automatic builds in the cloud that run all your tests for you. But first, at the heart of every automation script is the need to actually build your app.

xcodebuild build -scheme Emitron

xcodebuild syntax

When calling xcodebuild, you specify an action and a list of options.


There’s a variety of actions you can use with xcodebuild. Most of them correspond to actions available in Xcode, such as build, clean, archive or test.


Options are like parameters you use to configure your chosen action. Earlier, you used -scheme Emitron to specify that xcodebuild should build the Emitron scheme. Here are some other available options:

Archiving Emitron

You’ve learnt how to create a regular build of Emitron, but that’s not enough for your automation script. If you want to automatically upload Emitron to App Store Connect, you need to create an archive build first.

xcodebuild archive -scheme Emitron \
  -configuration Release \
  -archivePath "Emitron.xcarchive"

Exporting Emitron

So far, you’ve archived Emitron into an .xcarchive file. An .xcarchive isn’t signed; so, it’s not ready for upload to App Store Connect. To get a signed binary, you need to export your archive into an .ipa.

Creating an export options file

Since you don’t have a fancy UI to guide you through exporting an archive in xcodebuild, all the configuration needs to be set up front. That’s where the export options file comes in.

touch ExportOptions.plist
<!-- 1 -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">
<!-- 2 -->
  <!-- 3 -->
  <!-- 4 -->
    <string>Emitron App Store</string>

Exporting the archive

With an export options file, you’re ready to export Emitron into an .ipa that you can upload to App Store Connect.

xcodebuild -exportArchive \
  -archivePath Emitron.xcarchive \
  -exportOptionsPlist "ExportOptions.plist" \
  -exportPath .

Uploading Emitron to App Store Connect

Using the command line, xcodebuild can upload Emitron straight to App Store Connect. With one new option in ExportOptions.plist, xcodebuild will upload your .ipa instead of leaving it in the project folder. That means there’s no need to use any other tools to upload your build.

xcodebuild -exportArchive \
  -archivePath Emitron.xcarchive \
  -exportOptionsPlist "ExportOptions.plist" \
  -exportPath .

Bumping the build version

When you upload a build to App Store Connect, its build version has to be unique. If it isn’t, you’ll get a Redundant Binary Upload error when xcodebuild tries to upload the exported archive.

Tying it all together

Using xcodebuild to manually build and upload Emitron gets you out of Xcode, but there’s not much benefit beyond that. You still haven’t automated the process.

#!/usr/bin/env bash

# 1
xcodebuild archive -scheme Emitron \
  -configuration Release \
  -archivePath "Emitron.xcarchive"

# 2
xcodebuild -exportArchive \
  -archivePath Emitron.xcarchive \
  -exportOptionsPlist "ExportOptions.plist" \
  -exportPath .

Granting file permissions

Every file has a set of permissions that determine who can read, write or execute it. You need permission to execute if it’s going to be of any use.

chmod u+x

Running the script

Now that you have the permissions to do so, run the script in the terminal:


More possibilities with automation

In this chapter, you learned how to build, archive, export and upload Emitron using xcodebuild. It’s a great start, but automation can go much further than creating a build and uploading it to App Store.

Key points

  • Automation saves time, shares knowledge and prevents mistakes.
  • Automating your build is the first step towards continuous integration.
  • xcodebuild is the tool that Xcode uses to build your app. You can use it too, via the command line.
  • To upload a new build to App Store Connect, you need to export an archive as an .ipa.
  • xcodebuild needs an export options file to export an archive.
  • By setting destination to upload in an export options file, xcodebuild can even upload an exported archive directly to App Store Connect.
Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2024 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now