I craft user-friendly applications

San Francisco, reddit, WomenWhoCode, CocoaPods

The Project File Part 2: Schemes and Targets

Welcome to part 2 of my Project file series! Before reading this post, I suggest familiarizing yourself with part 1.

Schemes and targets are the building blocks of apps in Xcode. Every app has at least one scheme and one target. Just like everything else in Xcode’s build system, these have representations on disk that are used to keep track of the settings needed to build.


Before digging into some of the details on how schemes and targets work, there are a number of terms that need to be defined.

  • Product: Apple’s term for the output of a compilation. There are set pre-defined target types: application, test, static library, and framework to name a few.
  • NativeTarget: a set of instructions for building a product. These usually go un-qualified because they are much more frequent than the other kinds of target.
  • Aggregate Target: a set of instructions for building multiple targets. This is flexible and can be used to do pieces of work that don’t output a product. Example: mogenerator is run with an aggregate target but outputs no built product.
  • Legacy Target: a set of instructions that calls a command-line system for building. If a project needs a dependency that needs to run make to build, this is the kind of target to use.
  • Scheme: a set of instructions for building one or more targets. This is the top-most instruction set that Xcode uses and only one can be active at a time. Schemes also have the ability to be private or public. By default, every Xcode project is created with 1 target and 1 public scheme, which is the minimum requirement for building in Xcode.


All target information is saved in the .pbxproj with the type PBXNativeTarget or PBXAggregateTarget. Here’s what a simple target looks like:

D9B6428F176A2E17003D8169 /* Catstagrame */ = {
            isa = PBXNativeTarget;
            buildConfigurationList = D9B642C5176A2E17003D8169 /* Build configuration list for PBXNativeTarget "Catstagrame" */;
            buildPhases = (
                5886B8DBD5B540EDADB3C9A3 /* Check Pods Manifest.lock */,
                D9B6428C176A2E17003D8169 /* Sources */,
                D9B6428D176A2E17003D8169 /* Frameworks */,
                D9B6428E176A2E17003D8169 /* Resources */,
                291A5E171FA24E5AA4E0C13F /* Copy Pods Resources */,
                D9847C20177F8CA400C3F95B /* Copy Key */,
            buildRules = (
            dependencies = (
            name = Catstagrame;
            productName = Catstagrame;
            productReference = D9B64290176A2E17003D8169 /* Catstagrame.app */;
            productType = "com.apple.product-type.application";

The keys within this object should look fairly familiar—they correspond with information we see within the project view in Xcode. $(TARGET_NAME) is retrieved from the name field. The buildConfigurationList populates the Build Settings tab, buildRules populates the Build Rules tab, and buildPhases and dependencies are shown in the Build Phases tab. The productReference is the UID used to refer to the built product, not the target itself even though they can appear to be very similar.

Product Types

Even though we only have 3 kinds of targets, only PBXNativeTarget has multiple product types. When adding a Legacy or Aggregate product, productReference and productType are missing from the entity. The most common types of products are fairly self-explanatory:



One really interesting tidbit about tvOS targets is that they are listed exactly the same as iOS targets. The main tvOS application is a com.apple.product-type.application. All of the entries are the same as an iOS app, with a few different build settings set in the XCBuildConfiguration section:

SDKROOT = appletvos;


Schemes are saved in a separate xml file, within xcuserdata or xcshareddata. Most repositories ignore xcuserdata since Xcode also put things in there like breakpoint settings that shouldn’t be shared between developers. These .xcscheme files are standard xml, not plists like many other files used by Xcode internals. Like the .pbxproj this is not a full representation of scheme data—there is an internal-to-Xcode set of flags that it overrides.

At a quick glance, this file appears to be fairly generic. In reality it is tightly coupled to the project file and targets therein. Every target that is explicitly included in the scheme is referenced within the .xcscheme by UID. Because of this, these cannot simply be copy-pasted between different Xcode projects and “just work.”

This file is auto-generated by Xcode, and just like the project file will be overwritten on a regular basis. Edits to this file should only be made while the corresponding Xcode project is not open.

The root of this file includes information for performing all of the different actions within the project: build, test, launch, profile, analyze, and archive. Unlike the project file, there are no key/value pairs that reference a particular entity so as you read through it, you will notice many references that look the same. The name of the scheme is the name of the file.

<?xml version="1.0" encoding="UTF-8"?>
   LastUpgradeVersion = "0500"
   version = "1.7">

All of these Actions are named the same as they are used in Xcode except for LaunchAction which is actually Run.


Dependencies are referenced within each of the sections within a BuildableReference entry. The presence of one of these means that action is dependent upon Build happening first, which is the case for all other Actions. Unlike in the project file, the same BuildableReference is included several times to refer to the same target. There is also a reference to the project file that contains the target. The UID is referenced by the BlueprintIdentifier key. The project file the target comes from is also included.

   BuildableIdentifier = "primary"
   BlueprintIdentifier = "3AA4FE2703EA4DC3A89C1CCC"
   BuildableName = "libPods.a"
   BlueprintName = "Pods"
   ReferencedContainer = "container:Pods/Pods.xcodeproj">


The Build Action is the only action that refers to multiple targets. As such, it includes a list of BuildableReferences within BuildActionEntries that refer to the explicit dependencies specified by the contained targets. These come from Target Dependencies or Link Binary With Library where the library is also a target within the workspace. All other Actions nest the BuildableReference inside whatever needs to reference the product.

   runnableDebuggingMode = "0">
      BuildableIdentifier = "primary"
      BlueprintIdentifier = "D9B6428F176A2E17003D8169"
      BuildableName = "Catstagrame.app"
      BlueprintName = "Catstagrame"
      ReferencedContainer = "container:Catstagrame.xcodeproj">

Another difference between schemes and the project file is that each action has a different set of configuration options. All actions have pre- and post- actions that can be performed before the main action, but that is the only consistency between action types. Analyze and Archive have the fewest options whereas Launch has the most. This mirrors the Edit Scheme dialogue in Xcode.

   buildConfiguration = "Debug">
   buildConfiguration = "Release"
   revealArchiveInOrganizer = "YES">


All of the actions have options associated with them. These are included in the opening tag of the Action as attributes. Not all of the options that show in the Xcode Edit Scheme menu are listed, and some only appear when they are turned on.

   buildConfiguration = "Debug"
   selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
   selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
   launchStyle = "0"
   useCustomWorkingDirectory = "NO"
   ignoresPersistentStateOnLaunch = "NO"
   debugDocumentVersioning = "YES"
   debugServiceExtension = "internal"
   allowLocationSimulation = "YES">

For example, turning on Localization Debugging adds showNonLocalizedStrings = "YES" but when turned off the attribute is simply missing. On the other hand, allowLocationSimulation is present regardless of whether it is enabled or not.

Run options screenshot

Pre- and Post- Actions

There are only 2 kinds of pre- and post- actions available: send email and run script.

The Send Email action will open up Mail.app on your computer and send an email from your default email account. There’s no way to add any variables or conditionals. Oh and attachLogToEmail doesn’t appear to do anything.

   ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.SendEmailAction">
      title = "Send Email"
      emailRecipient = "thedoctor@tardis.space"
      emailSubject = "Sup"
      emailBody = "Bowties are cool"
      attachLogToEmail = "NO">

The Script action is much more useful. It can run in any shell in any language you have installed. However, just like with the PBXShellScriptBuildPhase the script will be contained within the scheme file. Thankfully it will automatically escape quotes to &quot;. By default, this is run from within the build directory. So if your goal is to modify contents of the workspace, you can cd ${SRCROOT}.

So for this script:


pod install #>> /tmp/output.txt

It gets saved as:

   ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
      title = "Run Script"
      scriptText = "cd ${SRCROOT}&#10;&#10;pod install #&gt;&gt; /tmp/output.txt"
      shellToInvoke = "/usr/bin/env bash">
            BuildableIdentifier = "primary"
            BlueprintIdentifier = "D9B6428F176A2E17003D8169"
            BuildableName = "Catstagrame.app"
            BlueprintName = "Catstagrame"
            ReferencedContainer = "container:Catstagrame.xcodeproj">

All of the flags passed into the build are available for use within these actions, including things like ${PRODUCT_NAME}. Note: Any sort of echo or print will not show up in the build logs, console etc. Send output to a file in order to see what’s going on.

One other nifty fact: changing the titles does also update them in Xcode. So you can send a REALLY COOL email for instance.
title is Send a REALLY COOL email image

In Conclusion

Schemes and targets are the building blocks of our applications, and it turns out they are fairly complicated. Thankfully the naming conventions used in the project and scheme files is fairly explicit and easily tied into Xcode’s views of the same information. Configuring these at a deer level than the defaults that Xcode provide can simplify many processes and automate common tasks. Xcode is a powerful tool. But we all know: with great power, comes great responsibility, so edit wisely.

Test Logs in Xcode

Apple spent the week of WWDC touting the new testing features in Xcode 7. One thing they failed to mention both this year and last was the persistence of test results to disk. These files and folders are not officially documented, so if you decide to rely on them make sure to check a new version of Xcode doesn’t break anything. This post will be updated to reflect changes as needed.

If you run a set of tests in Xcode 6/7 or with xcodebuild test via the command line, a new folder inside of the app’s folder in DerivedData is created, called Test. It contains similar files to the other folders, but Xcode 7 adds some new things as well.


An .xcactivitylog is a gzipped copy of the build log that’s generated any time a project is built. Each file is uniquely named with a UUID. Unfortunately for us, the UUID generated is unique per folder, so correlating a file in Build and Test cannot be done by file name alone. These appear to be segments of the output, not complete logs. At least one of these is generated per build.


This is the exciting part. This file contains the results of the tests in a machine readable format. At the root of this plist is 3 things: FormatVersion, RunDestination, and TestableSummaries.


This is a string that is used to version the TestSummaries file format. Between Xcode 6 and 7, the version number did not change, though additional information is added to the files generated in 7. With this, we can assume that the version is not incremented when additions are made to the objects contained.


This contains information about what computer, device, and sdk were used to run the tests. All the items are fairly self-explanatory.


Each test target is an item in this array. As of Xcode 7, running test will automatically run all test targets associated with a project.

Within the Tests array there are records of the test, but they are quite buried. The top-level item distinguishes between All tests or Selected tests. The only difference between these two is how many levels of Subtests exist between the top level Test object and the individual test results.

In All tests the identifier hierarchy looks like so

All tests
    └── AppTests.xctest
        └── AppTests
            └── Individual tests   

For Selected tests the .xctest level is skipped.

Selected tests
    └── AppTests
        └── Individual tests   

Once we get down into individual tests, the Identifier is automatically generated based on the method name. so -(void)testExample becomes AppTests/testExample. When using Specta, the names are mangled slightly more.

Take this test for example:

describe(@"successful request", ^{
     it(@"calls success block when request succeeds", ^{

The TestIdentifier generated will look something like this: AppTests/test_successful_request__calls_success_block_when_request_succeeds.

Tests written in swift will always end with ().

Xcode 7 adds ActivitySummaries and FailureSummaries

For Unit test targets, the useful piece of information here is the reason the test fails. For UI test targets, this is where the steps to perform the UI tests are recorded, along with any extra information about them. When running a UI test, each action taken on a UI object generates one of these sub activities.

Take this test:

    func testOne() {
        let app = XCUIApplication()
        let aTextFieldTextField = app.textFields["A Text Field"]

Sidenote: the test must tap a textField before it can enter text into it.

This test generates 4 activities, with sub activities auto-generated:

    t =     1.77s     Wait for app to idle
    t =     2.42s     Tap the "One" Button
    t =     2.43s         Wait for app to idle
    t =     2.68s         Find the "One" Button
    t =     2.72s         Dispatch the event
    t =     2.97s         Wait for app to idle
    t =     3.62s     Tap the "A Text Field" TextField
    t =     3.62s         Wait for app to idle
    t =     3.62s         Find the "A Text Field" TextField
    t =     3.64s         Dispatch the event
    t =     3.87s         Wait for app to idle
    t =     4.49s     Type 'asd' into the "A Text Field" TextField
    t =     4.49s         Wait for app to idle
    t =     4.49s         Find the "A Text Field" TextField
    t =     4.55s         Dispatch the event
    t =     4.66s         Wait for app to idle

The step we care about most is “Dispatch the event” because it contains the attachments generated from the tests.


Xcode 7 introduced UI testing, a big part of which is screenshots of the tests as they happen. The Attachments object contains information about where those screenshots live. But there’s more! In addition to a .png of the screen during that particular test step, there’s also a snapshot. What is a snapshot? It’s a archive containing the entire view hierarchy on screen when the screenshot was taken as a binary plist.


When a test fails, a summary is added to the FailureSummaries key. This is just a shortcut to the item in ActivitySummaries which has almost the same information.

Xcode vs xcodebuild


Thankfully for those of us who automate builds, xcodebuild test does the same thing that Xcode does, though it generates fewer files. Here’s what you’ll find in Logs after running on the command line:

├── Build
│   ├── Cache.db
│   └── FCDDA053-2DA1-4C1C-8716-B6C339CB5815.xcactivitylog
└── Test
    ├── 21ED62CB-4F14-4A87-805E-C594936F24E6_TestSummaries.plist
    └── Attachments
        ├── Screenshot_6CD674C6-4E0D-4DAC-BF66-016198C32780.png
        ├── Screenshot_8126D5ED-88B9-4F6D-8F38-A339F3A14AE5.png
        ├── Screenshot_94513284-AA2F-48DC-A9D7-C56A0EF9BC91.png
        ├── Screenshot_E6EBC6AC-7311-49C2-829D-AF9880141C4B.png
        ├── Snapshot_5638F5F5-C04C-4F5E-AE42-C517B6B1FCBC
        ├── Snapshot_57F67566-9E22-4005-B7D6-B822EF08CD2E
        ├── Snapshot_7AA349A8-CF54-4AC4-8139-A676167C8801
        └── Snapshot_A065B515-A4DE-431C-B72F-87952AA133A6

One caveat: The .xcactivitylog in the Build folder does not contain the full build log. It is missing the logs generated when tests are run.

Now this seems great, but remember this is inside of DervivedData so there will be many other files, so finding it programmatically is not easy. One solution is to grep the console output for the sessionIdentifier which is included in the XCTestConfiguration:

Found configuration <XCTestConfiguration: 0x7ff38a5894e0>
                  sessionIdentifier:<__NSConcreteUUID 0x7ff38a58bf70> CC966A22-0E28-4880-B445-9E401BB24CDB

Manually sorting through Xcode’s logs is The Hard Way™ and finally with Xcode 7 there is an easier way to get that information.

There is a new xcodebuild argument resultBundlePath which will save the .xcactivitylog, TestSummary.plist, and related files to a directory of your choosing. As of Xcode 7b1, this must be an absolute path.

$ xcodebuild test -scheme 'Buttons' -destination 'platform=iOS Simulator,name=iPhone 6,OS=9.0' -resultBundlePath '~/Desktop/build'


├── 1_Test
│   ├── Attachments
│   │   ├── Screenshot_1236AC16-AF8C-4E87-A748-4867EAB120FC.png
│   │   ├── Screenshot_52E63346-D71F-4A6B-ACA9-736AD54854F3.png
│   │   ├── Screenshot_7A8F0CD6-3981-47FD-BC2D-DC6B35863656.png
│   │   ├── Screenshot_E4792BBC-9717-4BD1-8CD0-D560E19A491D.png
│   │   ├── Snapshot_273B4980-BE03-4EA8-81B7-03F237772558
│   │   ├── Snapshot_86786328-081A-4314-ADC9-213648471F5D
│   │   ├── Snapshot_AA3A1ADC-84C8-4FCC-91A6-590431B89210
│   │   └── Snapshot_CDCA9CA4-847D-46DF-852F-8BCEF0C468AE
│   ├── action.xcactivitylog
│   ├── action_TestSummaries.plist
│   └── build.xcactivitylog
├── Attachments
│   ├── Screenshot_2750BC84-575E-4849-9A39-820FB8D8E998.png
│   ├── Screenshot_59E390A6-9B39-4FD5-AA13-6915C211F6F8.png
│   ├── Screenshot_8F1BB0EE-1146-4CE0-BB5B-1ED473A12173.png
│   ├── Screenshot_DF5341F9-2763-47C6-821B-2B157E88AEC7.png
│   ├── Snapshot_21D3F473-0F28-4F4A-97FD-F30263461422
│   ├── Snapshot_5AF107B1-7CA0-4B14-9EEB-3918E4C4B5E9
│   ├── Snapshot_5F74DD59-6225-40D7-955A-21B366A563BD
│   └── Snapshot_FD2ED335-1729-4489-8B7F-0777E73D4EE8
├── Info.plist
└── TestSummaries.plist

There is duplicate data here. The TestSummaries.plist at the root of the directory is version 1.1, but inside 1_Test is the correct version. This also adds both build and test .xcactivitylog files conveniently in one place. Using CI? This argument will make your life a whole lot easier.


It is common knowledge that when Xcode builds a project, it does not do the same thing that xcodebuild does. Just like xcodebuild, building in Xcode creates a Test folder inside Logs, and saves summary plists and attachments. However, Xcode itself creates a lot more logs.

├── Build
│   ├── Cache.db
│   └── D0C828D2-21CA-4182-9A0E-C80DE1F8FA86.xcactivitylog
├── Debug
│   ├── 130CC81E-789E-4FDD-A156-DB75FBEBC770.xcactivitylog
│   ├── 44845FEA-0D87-4266-AD62-502E0F4C30B2.xcactivitylog
│   └── Cache.db
├── Issues
│   ├── 0F1BB6CD-F28B-48DB-9A09-B3948257D698.xcactivitylog
│   ├── 4AFC3EE7-12EC-4E4C-BDF9-2ED7BCA6887E.xcactivitylog
│   ├── C32CA334-AAF9-43B4-AB00-D10373391A08.xcactivitylog
│   └── Cache.db
└── Test
    ├── 9309CF06-A5BB-418C-91D5-299788C685A3.xcactivitylog
    ├── 9309CF06-A5BB-418C-91D5-299788C685A3_TestSummaries.plist
    ├── Attachments
    │   ├── Screenshot_556D54FE-235B-4A3E-A00E-C34ED00AF043.png
    │   ├── Screenshot_786546BC-98C4-4788-B7F1-9A66DFA0EF51.png
    │   ├── Screenshot_976F8BF7-C2A6-4E8F-8BFC-EE6A4FA6D78E.png
    │   ├── Screenshot_BC2D4BF7-DC31-459F-B726-84651CFF52A3.png
    │   ├── Snapshot_31A23466-8A83-42B6-8AD7-4CBD2FB34BB7
    │   ├── Snapshot_626616A0-436F-4D45-822B-41E21E7E80CF
    │   ├── Snapshot_73A33739-49A0-4D8E-9295-338BDAE08C5C
    │   └── Snapshot_83BF8F36-C1EF-45E0-B55E-3320F7FE55D7
    └── Cache.db

When opening up the multiple .xcactivitylog files, there is some overlap. It appears that Xcode will split the different sections of the build into different activity logs. Unfortunately, because the UUIDs are unique and not related, putting a full log back together from these pieces is fairly difficult.


These new files and flags will make automated builds even better with Xcode 7. Apple has finally rounded out the toolset for automating tests, and CI providers are already starting to offer builds using Xcode 7.

The sample project used in this post is available on Github.


  • Lawrence Lomax for telling me about the new resultBundlePath option.
  • Brian Nickel for fixing the sample project’s storyboard overriding accessibilityLabel.

The Project File Part 1: Composition

The project file, specifically the project.pbxproj, is the closest thing to taboo we deal with on a regular basis as iOS developers. We tip toe around it, because we don’t want to break it. After all, without this file we can’t compile, and if we can’t compile, we can’t build apps.

Object Graph

At it’s heart, this file is an object graph. All of these objects correspond with some sort of action you do in Xcode. This is the master list of files, target composition, build settings, etc. Each item is referenced by a UID.

One of the most important things to learn about the project file is that these UIDs must not be changed. They need to be consistent within the file, otherwise Xcode cannot open your project. Conversely, if there are extra, unused references, Xcode doesn’t care.

Traversing the graph is pretty simple. It’s just a matter of picking a UID and finding it elsewhere in the document. There are a number of intermediary objects to go through to find a particular target that contains a particular file, the files in a build phase etc.


As you scan through this file, you’ll note that every object has an isa field. These names (likely) correspond with the actual objects created when you open the file. For the purpose of this exploration, I’ll be referring to these objects as Classes. And, for the most part, they are all prefixed with PBX or XC for consistency. Here is the full list as of Xcode 6:


Just like most of Cocoa, these are fairly self explanatory. But there are a few that stand out.


This object holds all of your build settings, including compiler version, provisioning, code signing, info plist, etc. By default, this is not very large because unlike other sections of the project file, it is essentially a diff versus the default build configurations.


This represents a target for your app. It contains references to the build configuration, build phases, product, etc. This is also how each target can have different settings from the project file. This UID is used both internally to the .pbxproj and externally, as you’ll see later.


Yes, this is exactly what you think it is. This is the most common item to find in the project file, and this is usually the spot that gets messed up. This contains the path to the file on disk, as well as meta-info about the file, such as its type. And of course, this also has a UID.

Build scripts/steps etc.

One of the most interesting aspects of the project file are the inclusion of build phases. This is one of the spots where the names don’t quite equate to what you’d assume. And, just like everything else, this section references other objects that represent each kind of build phase. This includes the two most common areas for file conflicts, PBXSourcesBuildPhase and PBXCopyFilesBuildPhase. When working with a version control system like git, these are the areas that most frequently change, and therefore have the most conflicts.

One of the most interesting bits I’ve found is that a run script build phase’s contents are added directly to the project file. So if you’re wondering why Xcode complains about quotes sometimes, this is why. I do not suggest you modify these directly.

Other important files (workspace)

When exploring the contents of the .xcodeproj you’ll notice a few other files floating around. The most important one is the .xcworkspace. As of Xcode 4, every .xcodeproj contains a workspace, but this fact is hidden from the user. This is also how Xcode handles subprojects, and can easily recruse through them. This is just a standard XML file.

The other files of note can be found in the xcschemes directory inside xcshareddata. By default, Xcode assumes that there is a single scheme linked to the single target. If the project contains any shared schemes they will be here. These are also plain XML documents. These contain information on how to build the scheme, with a reference to the UID representing the target in the project file. Just like build phases, if you have any pre- or post-action scripts, they will be included as strings in this file.

In Conclusion

The project file is a formidable document, but it’s not as complicated as most would think. Everything is laid out in an orderly fashion, and once you understand its paradigms you’ll find working with it much easier.

In Part 2 I plan on exploring strategies for some of the common pitfalls we run into when working on a team.

Why your early-stage startup doesn't need a lead engineer

I’ve seen the insides of many companies, and like most engineers am inundated with recruitment emails. One in particular gave me inspiration to explore the needs of early stage companies when it comes to hiring talent. And so Why your early-stage startup doesn’t need a lead engineer was born on Medium.

My #CHIMEHACK Experience

I was really excited to be involved in Women Who Code’s first Hackathon, as a judge. It was a fantastic 3 days, and I really enjoyed seeing all the teams and what they produced.

I was so impacted by that event, that I shared some takeaways, and a challenge on Medium. Head on over and take a look: My #CHIMEHACK Experience on Medium.

CocoaPods Under the Hood @ objc.io

This month I wrote on some of the internals of CocoaPods, and explored the bits that make it tick.

Check it out in objc.io Issue #6.

Automated Testing with GHUnit and KIF

Testing in iOS is something that we as developers don’t really think about, or do. Writing tests can help us write code that lasts for years to come. But, this post isn’t about why you should write tests, it’s about how to use GHUnit and KIF with Jenkins CI.

There are two main types of testing frameworks, Unit and UI. OCUnit, which ships with Xcode, and GHUnit are both Unit testing frameworks. UIAutomation, Frank, and KIF are examples are UI testing frameworks.


Unit tests are used to test vertical, isolated slices of functionality. Your app won’t actually be running when these tests are run. Instead, you’ll only import and create objects you want to test directly.


GHUnit has some fantastic setup steps. The most important thing to note is that GHUnit has its own target, which is not a duplicate target of your app. This means that your app will not actually be running when the tests run.

Writing Tests

All of your tests will be subclasses of GHTestCase. And you can group these together by creating a GHTestGroup. If you’ve used OCUnit before, this should all sound familar.

Each test case will determine sucess or failure by using assert macros (you can see a full list of them on this page).


GHUnit also happens to have a great guide for setting up tests using CI. Note that if you’re running Xcode 4.5 or newer there is a bug where the old way of running tests does not work. This is being actively tracked in GitHub Issues for the project, as well as on openradar.

GHUnit also will output JUnit test results, which Jenkins can track over time. This is great for keeping track of code stability, and for finding trends in how well your tests are doing.


Arguably the hardest part of automated testing is the fact that it’s been broken since Developer Preview 3 of Xcode 4.5. This means that you have to work around the command line tools in order to get your tests to run. It’s something that is actively being tracked, and there are solutions, but they are far from ideal.

Since your app won’t be running during these tests, everything you test is very isolated. That might be great for your app, but not all apps can be tested thoroughly with only small pieces running at a time.

Also, since your app is not actually running, running UI tests with GHUnit is not ideal.


KIF is a framework created by the folks at Square. It uses the <UIAccessibility> protocol to interact with your app, which is a private API. When adding KIF to your project, you have the choice of using git submodules, or Cocoapods.


KIF setup is fairly simple, and is documented in the project’s README. The main difference between KIF and GHUnit is that KIF duplicates your application target, so all of your source code is added to KIF.

The Test Controller determines at runtime what tests to run, if you don’t want to run all of them (which you won’t). You can choose to run different sets of tests based on just about anything, the iOS version of the device, the device idiom, etc.

KIFTestScenario & KIFTestStep The bulk of your test writing will be creating scenarios, like “user logs in” or “user visits cart”, which are comprised of steps. To create reuseable steps, you subclass KIFTestStep, and then can define your step using blocks. Likewise, you can subclass KIFTestScenario.


In the KIF README there is a section on Automation that provides instructions, and a bash script, for getting it running. However, I’ve found that ios-sim works a bit better, but both work.

KIF doesn’t automatically output test results in any useable format. There’s currently a pull request open to get that in. Or, you could get a patch from an older pull request, which is the one I’ve been using for months. Either way, you need to fork KIF.

Here’s a simple command to run KIF with an .app file stored in $APPFILE and then save the JUnit xml:

/usr/local/bin/ios-sim launch $APPFILE --family ipad > /tmp/KIF-ipad-$$.out 2>&1
cp "`grep "JUNIT XML RESULTS AT " /tmp/KIF-ipad-$$.out | sed 's/.*JUNIT XML RESULTS AT //'`" 'test-reports/KIF-ipad-results.xml'


KIF is fast

KIF runs at processer speed. It doesn’t have a “reaction time” like people do, so KIF will try to find that view on the screen before your navigation push animation finishes. To compensate for this, you’ll end up doing a lot of:

[scenario addStep:[KIFTestStep stepToWaitForTimeInterval:1 description:@"wait"]];
[scenario addStep:[KIFTestStep stepToWaitForViewWithAccessibilityLabel:@"Table"]];

Now, this isn’t necessarily a bad thing. But it will take time to get in the habit of thinking to add waits into your tests. And tests will take longer to run, of course.

KIF can’t recover

KIF has a handy way of adding a step, or set of steps, to be run before every scenario:

[KIFTestScenario setDefaultStepsToSetUp:[KIFTestStep setupSteps]];

However, in these default setup steps you need to be able to recover from a failure at any point in your app. If you don’t recover, then there’ll be a domino-effect of failed tests. This will mean having methods available to esentially reset the application state.

You’re code coverage will not be evenly distributed

If your app requires a login for example, it’s likely you’ll have something like this in many scenarios:

[scenario addStepsFromArray:[LoginTestStep stepsToLoginWithEmail:TEST_EMAIL password:TEST_PASSWORD]];

Because you want to “reset the application state” between scenarios, you’ll end up testing the parts of your code that deal with common actions more frequently than other parts of your app. This is both a pro and a con; the parts you test over and over will definitely be rock solid, but that means there will be parts of your ap that won’t be tested nearly as much.

KIF can’t see off the screen

Since KIF relies on <UIAccessibility> and that relies on view drawing, KIF can’t see things that are off the screen. You’ll end up frequently doing something like this:

[scenario addStep:[KIFTestStep stepToScrollToItemWithAccessibilityLabel:@"Settings"]];
Fork it

KIF is a great framework, but Square has an “Individual Contributor License Agreement (CLA)” that you must sign before any of your code can go into core. This means that there are a number of great things that developers have made, but never got merged in (like the JUnit code).

In Summary

Does writing tests help you write better code? Yes.

Will testing add to development time? Yes.

Is it worth the extra time? Yes.

If you’re interested in seeing some sample tests, head over to my Github repo.

Automated Testing with GHUnit and KIF from micheletitolo

How To Make APIs That Don't Suck

As a mobile developer, I use a lot of APIs. I’ve worked with some really great ones, and some ones with lots of room for improvement. Here are a few lessons I’ve learned that hopefully you can think about the next time you are developing, or working with, a new API.

For the sake of this argument, an API is any way a 3rd party can communicate with your software. This includes both web services, and releasing a library that other developers can add to their own code base.

Lesson 3: Follow Conventions

Conventions have been established for many reasons, most often because they just make sense. If you’re going down a path that you haven’t been before, following conventions is a good place to start. As a developer, you’ll be able to learn from the wisdom of many before you, and you’ll end up producing a product of greater quality than if you were to code in a box.

Another important reason to follow conventions is the fact that problems will be easier to debug. The last thing you want, when letting others interact with your software, is for you to do hours of support (which take away from development time). This will greatly help developers working with your API.

If you are going to establish your own convention, which you will for a variety of reasons, make sure you are consistent. Adding paging, for instance, should be the same across all of your calls that support it; don’t go changing one API in a set to be different. Consistency is a big part of following conventions, regardless of who defined them.

Lesson 2: Don’t Be Clever

As programmers, we like to think we’re pretty smart. We like to find the best solution to a problem. Sometimes, however, this leads to us being clever. Clever is a pitfall, and it makes everyone’s life more complicated.

When making an API it’s your responsibility to make things as dead simple as possible. Consumers of your API want access to your data as easily and quickly as possible. Keeping things simple will make everyone happy, especially in the long run.

Lesson 1: Document, Document, Document

Did I say document? The purpose of an API is to be reused. If it’s not documented well, then it will be very difficult to use in the future. Expect the code you’re writing now to have at least a 5 year lifespan. Will you still be working on this one thing in 5 years? Probably not; you may not even be at the same company by then.

Writing good documentation is a requirement these days when releasing an API to the public. Documenting code is a skill that every developer should have, so take this opportunity to better your skills at it.

Screenshots and examples are also good things to include. If you want to go above and beyond, include an API console on your website, so people can play with it without the mess of a local client.

Lesson 0: Expect the Unexpected

Once your code goes live, people will start using it. And since we’ve established a timeline of at least 5 years, whatever you build now will be used in a different purpose in the future.

If you follow the first 3 lessons, this one will be easy to handle. Documentation is by far the most important thing to have, so make sure it’s easy to find and well written.

In Summary

In summary, APIs are becoming a vital part of your software stack. These are just a few lessons I’ve learned over the years I’ve been working with APIs. Obviously, some rules are meant to be broken. We all work in different ways. These are just some tips to help you in your creation!

Using Foundation (not Bootstrap)

Twitter’s Bootstrap has become the go-to toolset for most startups and web apps these days. It’s easy to see why, as it has pretty much everything a web app would need to get off the ground, including JS tools.

New layout woo

I’m really excited about this new layout. It’s much more modern than the old one, but keep in mind this is still a work in progress. There are a few things I have left to fix, especially on mobile *cough*Android*cough*.

One thing to note. I have removed my ‘Work’ section entirely. Why?

There are great tools out there, now, that display my work experience in a more cohesive manner, as well as show things like connections and endorsements. It’s also one less dependency for me to keep updated. Honestly, who needs another thing to update these days? Checkout my Linkedin or Zerply profiles if that’s really what you’re looking for.

Oh yeah, and the ‘About’ page is gone too. Yep, 3 pages down to one. And it feels so good.

If you have any feedback, or find an issue with the new layout, please email me!

M0 out!