xctool

Control the build system, and you control the destiny of the language, its ecosystem, and community.

Objective-C has changed so very much in such a very short timespan. In just a few short years, the language has gone from humdrum NeXT vestige to a position of commanding influence. A significant portion of these prolific contributions from the open source community for Objective-C has been directly enabled and encouraged by increased ownership around tooling.

CocoaPods, in particular, exemplifies the compounding influences of technology and community. Now two years into the project, there are over 2,700 community-submitted libraries and frameworks that can be integrated into your own project with a simple pod install command.

Dependency management is just one of the many aspects of iOS and OS X development that have been dramatically improved by the community. Other examples include provisioning and distribution automation, bug reporting, and documentation.

But this week, our focus is on a tool that redefines the actual build process itself, to serve as the foundation for a new generation of tooling and integration: xctool.


xctool is an open source project by Fred Potter that came from his work on build system automation at Facebook. It is a drop-in replacement for xcodebuild, the utility underlying Xcode.app itself.

When you click “Build & Run” in Xcode, all of the project, build target, and scheme settings are passed to xcodebuild, which invokes build commands to create and then launch an .ipa executable on the device or simulator.

Don’t get me wrong—it’s a blessing that things work in this way, instead of, say, Xcode wrapping its own private build system in a way that was inaccessible from outside the application. But anyone who has ever attempted to interact with xcodebuild from Terminal.app can attest to its… less-than-streamlined experience.

Rather than belabor the point by enumerating all of the flaws in this decade-old utility, let’s cut to the hero of the story—XCtool—to show how it improves on the status quo:

Aesthetics & Style Points

The first you’ll notice about xctool is its gorgeous, colorized output.

xctool in Action

As consumers of Apple hardware and software ourselves, the role of design cannot be under-stated. In this respect, xctool absolutely nails it. Every step of the build process is neatly organized and reported in a way that is understandable and visually appealing, with ANSI colorization and a splash of Unicode ornamentation.

But xctool’s beauty is not just skin-deep: build progress can also be reported in formats that can be read by other tools:

$ xctool -reporter plain:output.txt build

Reporters

  • pretty: (default) a text-based reporter that uses ANSI colors and unicode symbols for pretty output.
  • plain: like pretty, but with with no colors or Unicode.
  • phabricator: outputs a JSON array of build/test results which can be fed into the Phabricator code-review tool.
  • junit: produces a JUnit/xUnit compatible XML file with test results.
  • json-stream: a stream of build/test events as JSON dictionaries, one per line (example output).
  • json-compilation-database: outputs a JSON Compilation Database of build events which can be used by Clang Tooling based tools, e.g. OCLint.

Build System Integration

Another major improvement over xcodebuild is that xctool will run application tests in your project in the same way Xcode.app does (xcodebuild can’t discern which targets in your scheme are test targets, let alone run them in the simulator)

For this reason alone, xctool has great implications for the emerging discipline of continuous integration testing within the Objective-C community.

Travis CI

Travis CI offers free continuous integration services for open source projects (as well as a paid plan for commercial software), and is rather unique for supporting Objective-C. It can be configured to run your test suite on every git push to GitHub (or your favorite SCM host), and will notify you if your most recent change-set breaks the build.

To add Travis CI to your own Objective-C project, create an account and webservice hook, and create a .travis.yml file in your repository:

.travis.yml

language: objective-c
before_install:
  - brew update
  - brew install xctool
script: xctool -workspace MyApp.xcworkspace -scheme MyApp test

OCLint

OCLint is a static code analyzer that inspects Objective-C (as well as C and C++) code for common sources of problems, like empty if/else/try/catch/finally statements,unused local variables and parameters, complicated code with high NCSS or cyclomatic / NPath complexity, redundant code, code smells, and other bad practices.

Remember xctool’s json-compilation-database reporter option? Well, that output can be read directly by OCLint to do its magical static analysis.

At the time of writing, there is still a ways to go before this becomes widely adopted, but my hope is that, now that the cat is out of the bag, some enterprising individuals might work together to make an insanely great experience around this promising tool.


Just as with the growth population within cities, infrastructure makes all of difference. One way or another, whether by local government mandate, emergent self-organization, or somewhere in-between, environments are changed to accommodate this growth.

Objective-C has and continues to undergo rapid growth based on the popularity of iOS. It is up to the community, in working with (and sometimes against) Apple to create infrastructure necessary to integrate so many new developers. How successful we are in this respect determines how we understand and communicate our roles and responsibilities as professional developers.

Are we clumsy amateurs, or do we take an active role in refining our craft?

xctool, like so many other tools from the community, provide hope and, indeed, inspiration about the future of the language and its ecosystem. Let’s continue to build upon these tools, to create a developer experience that we can be proud of.

NSMutableHipster

Questions? Corrections? Issues and pull requests are always welcome.

Written by Mattt
Mattt

Mattt (@mattt) is a writer and developer in Portland, Oregon.

Next Article

FileManager offers a convenient way to create, read, move, copy, and delete both files and directories, whether they’re on local or networked drives or iCloud ubiquitous containers.