When using Xcode to build and run your app, a collection of build settings referred to as build configuration is used to package the Application bundle.
To see what build configuration Xcode uses, open the Scheme editor. In Xcode choose Product > Scheme > Edit Scheme…, then select the Run action for the app.
“A build configuration specifies a set of build settings used to build a target’s product in a particular way. For example, it is common to have separate build configurations for debug and release builds of a product.” - Apple, 2011-05-09: XcodeConcepts, Build Settings
By default, Xcode uses the “Debug” build configuration, also used by Windmill, to build and test your app. To see what build configuration Windmill uses, open the Side panel. In Windmill choose View > Side Panel > Show Side Panel.
Equally like Xcode, Windmill uses the “Release” build configuration to produce the Archive bundle. The build configuration used by Windmill for the archive is also visible in the Side Panel.
How does that help?
There are at least two ways to take advantage of using a “Debug” and a “Release” build configuration for the development and release of your app respectively.
1. Conditional compilation
You can use a build setting, one for a Swift codebase and one for Objective-C, that allows you to conditionally compile a block of code.
In Swift that is the “SWIFT_ACTIVE_COMPILATION_CONDITIONS” or “OTHER_SWIFT_FLAGS” setting.
In Objective-C that is the “GCC_PREPROCESSOR_DEFINITIONS” setting.
By default, Xcode sets the value to “DEBUG” for both Swift and Objective-C under your Application target.
You can use this value as an identifier in your code to conditionally compile a code path. As an example, this can be helpful if you want to use a different endpoint during development than the release.
Some build settings specify a file to be used. A common one is the “INFOPLIST_FILE” setting which specifies which property list file to use when packaging a bundle.
As an example, for NSAppTransportSecurity you want to make sure that any exception rules you have for development don’t leak into your release build. This is the case if your development build uses different endpoints to your release one.
Windmill’s integration with Xcode’s build configurations gives you the ability to manage the development of your app towards a release in a streamlined way.
Regardless of how much you have a need for the “Debug” and the “Release” build configurations, Windmill uses them to build your app accordingly.
Did anyone try @windmill_io yet? It fill an interesting niche for indie devs that do not want to use hosted services for continuous integration. And unlike the Xcode bot mess, I trust @qnoid to actually make it work.
You can finally use a native macOS app alongside Xcode, which is highly integrated, to continuously monitor for code changes on your git repository, enabling you to always have your app ready to do a demo, public test or release.
Although Windmill requires next to no effort to get started, the initial release did not make it any easier to identify and fix failures than going through the logs. Here is where version 2.0 comes in, alongside many great features to help you with delivering a high quality app.
Windmill 2.0 highlights and surfaces build errors in a familiar way. This gives you a consistent view while debugging. It leaves no ambiguity as to how many errors there are, what these are and where each of them lies.
It is purposely designed in a way so that you do not have to learn new visual cues, communication language or put the mental effort required to associate Windmill errors to Xcode ones.
Since Windmill proactively builds your app for testing, you will get build errors for your test code too.
Another failure that Windmill will highlight is that of a test failing.
At a glance, you will be able to see if and how many tests have failed. In order to help you understand and cross check test failures with Xcode, Windmill will also give you a test summary.
More useful logs
As Windmill goes through your project, it will stop as soon as it encounters a failure. The Distilled Log will give you a more fine grained view of what Windmill was doing at the time of the failure (e.g. compiling a file) as well as a hint on how to fix it.
It is as simple to get started as opening your Xcode project/workspace. Windmill will also provide support along the way to recover from failures and works with even more project configurations than before.
To be part of an upcoming “Showcase” on the website please send screenshots of your app running on the Simulator alongside Windmill.
If there is anything preventing you from using Windmill or you have any feedback I would like to hear it.
If you are the only iOS Developer at a startup or a freelancer working for a client, please get in touch to better understand how Windmill fits into your development workflow.
You can reach me personally at qnoid under the Windmill domain or Twitter @windmill_io.
Windmill 2.0 lays the foundation for the future. With your support, what comes next is only a matter of time.
@qnoid Also interested on your thoughts as to processor overheads if developing and debugging whilst Windmill is running. Dev > commit > push > dev > commit > push ... is a common workflow for me. I wonder if Windmill might run at inconvenient times and slow this down?
For far too long us iOS developers have relied on Jenkins to, at the very minimum, automate checking out, building and testing our iOS apps.
Apple realised the need and in 2014 introduced Xcode bots as part of Xcode Server. In 2017, Xcode bots became part of Xcode bringing automation to the development Mac rather than explicitly requiring setting up a server.
Numerous cloud based services are also available that mirror Jenkins in terms of their offering when it comes to building and testing iOS apps.
Where are we today?
Jenkins appears to be the market leader according to MacStadium’s survey and anecdotal evidence seems to back this up.
Even though Jenkins is a generic “automation server”, its open source nature and plugin architecture has allowed1 the iOS community to provide support for iOS apps.
Setting up Jenkins requires considerable time and effort. It also assumes you are familiar with Apple’s Command Line Tools and feel comfortable using, what looks like, an ops tool.
There is only so much integration Jenkins offers with the rest of your iOS development process. Namely, any test devices to install your app to, or Xcode for App Store and Testflight distribution.
Xcode bots, almost 4 years later, hasn’t challenged Jenkins.
Xcode bots is a native offering, with out of the box support for building and testing your iOS apps. Going as far as providing both IPA and archive files.
It only takes a few clicks through a series of dialogs to setup, guiding you through the process. Before long, it will monitor for code changes, build, test, archive and export your app. It will even publish the IPA on a web server running locally so that you can install it on a device over the air.
Cloud based services
Cloud based services don’t seem to be focusing on iOS development. The exception being buddybuild that has recently been acquired by Apple.
Cloud based services typically mirror Jenkins and offer a scalable infrastructure. They too provide automation but typically leave it up to you to set them up.
As a result, like Jenkins, they require you to have knowledge of the tooling so that you can put everything together.
Unlike Jenkins, they don’t come “free”. Instead, limiting the work by some combination and factor of time, users and builds.
Should you wish to create an IPA and/or an archive you are expected to share your Apple account credentials or at the very least your signing certificate and private key.
Last but not least, access to your source code is mandatory.
Where does Windmill fit into all this?
At a bare minimum, an automation tool for iOS development must be able to provide support for the following scenarios:
check out the code whenever there is a new commit.
build the app, making sure it still compiles after any code merges.
test the code, making sure there are no regressions.
archive the build so that it is always ready to publish.
export an IPA so that the app can be run on a device.
Windmill does all the above as a native macOS app, built on top of Apple’s command line tools, taking into account existing conventions and development practices as defined and established by Apple.
It is designed to be at opposing ends to Jenkins by being easier to setup and maintain2. Also aiming to provide an “out of the box” level of integration paralleled to that set by Xcode bots. It offers support for all scenarios listed above as a standalone macOS app for free.
Windmill aims to bring a basic level of automation to building, testing and distributing an iOS app in a way that is both accessible and made ubiquitous to every iOS developer.
To achieve that, Windmill relies heavily on existing conventions as set by Apple and aims to establish a best practice on how to automate building, testing and distributing apps. At this stage, what Windmill is able to achieve and to what extent is defined by Apple. There is no way around it. This is a conscious decision. To pretend otherwise would be to rely on reverse engineering, side effects, undocumented features and observable behaviours. For bringing that basic level of automation it should be enough.
Windmill is not meant to be customised at this stage and definitely not in a way of writing and maintaining scripts. It is a slippery slope that leads to complexity, overhead and creates a dependency to those few people writing the scripts. As a result, there is currently no support for using third party tools or integrating with third party services.
Windmill takes its first step, looking into the future.
It is time iOS automation takes a leap when it comes to delivering apps. Not by zealously automating every step and integrating end to end. But by bringing sense, establishing a common understanding across iOS developers and businesses through a platform that focuses on what the goals are.
To safely make code changes. To have an app that runs on a device. To have a build ready for in house testing. To be ready for a demo. To have visibility on business metrics.
It is fair to say that this is just the beginning3 of Windmill. A humble, yet determined entry to make a mark in a crowded market with big players.
Windmill should be able to cover your needs today if you are:
using Jenkins just to checkout, build, test your app
an indie developer
an iOS freelancer working for a client
the sole developer in a startup
developing a side project
If you are indeed any of the above and there is a use case preventing you from using Windmill, I would like to hear it. You can reach out by posting to qnoid at windmill.io or on twitter @windmill_io
With Apple’s blessings by offering command line developer tools. ↩
There are no scripts to maintain and Windmill is, by design, only using the public, documented functionality of command line tools. Any breaking changes due to Apple updating the command line tools (as part of an Xcode upgrade) can still occur to Apple’s discretion. At which point, an upgrade to Windmill will be required. ↩
Windmill recognises that as a business grows, so does the complexity around delivering apps. As Windmill evolves, accessibility and ubiquity remain strong anchors. ↩