Subscribe to updates RSS logo

Developing an app towards its release

approx. 3 1/2 minutes read

Developing an app is more than writing code. It is about releasing it to the world. Windmill helps you establish a process, strongly aligned with Xcode, to support you along the way towards a release.

On every commit, Windmill builds the Application bundle as well as the Archive bundle. The Application bundle enables you to run your app on the Simulator, say to use the Xcode debugger to inspect and understand the view hierarchy of your app.

The Archive bundle is used to create your project’s IPA so that you can demo your app with your team and later prepare for a public beta using TestFlight or a release through the App Store.

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.

build configuration

“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.

archive configuration

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.

swift active compilations conditions flag

other swift flag

In Objective-C that is the “GCC_PREPROCESSOR_DEFINITIONS” setting.

GCC preprocessor definitions flag

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.

if debug

“Unlike the condition of an if statement, the compilation condition is evaluated at compile time. As a result, the statements are compiled and executed only if the compilation condition evaluates to true at compile time. The compilation condition can include the true and false Boolean literals, an identifier used with the -D command line flag, or any of the platform conditions listed in the table below.” - The Swift Programming Language (Swift 4.1), Apple, 2018-03-29: Language Reference, Conditional Compilation Block

2. File management

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.

Info property list file

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.

In closing

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.

Have a look at Xcode’s build settings to make the most of them for each build configuration.

Share your thoughts, experience and how useful Windmill has been so far to you. How has it changed the way in which you develop, iterate, get feedback and deliver your app?

If you are missing out, what’s preventing you from using it?

#PoweredByWindmill

Windmill 2.0

approx. 4 minutes read

Windmill was released on February 14th so that us, iOS Developers, could have an alternative to Jenkins for automating building and testing our iOS apps.

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.

Build Failures

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.

error summary

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.

Test Failures

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.

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.

distilled log

Simulator support

As part of building your app for distribution, Windmill will give you the option to launch the latest build of your app on the Simulator.

This can be useful when you want to check what your app looks like right there and then. It also enables you to install and run the app on the Simulator without access to the source code.

The app bundle

Each time you commit to master, Windmill will build your app bundle. You can choose to save it under the commit for future reference.

Terminal access

You can now use the Terminal to bring in any external dependencies (e.g. using Carthage or CocoaPods) to your project as monitored by Windmill. For a How-To, open the Windmill Help menu (⌘?).

Keep in mind that Windmill will not automatically update any dependencies as part of a new commit pushed to master.

terminal

What’s stopping you?

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.

One more thing…

Windmill already makes it easy to install your app on a device.

Running your app on an iPhone allows you to see how the app looks and feels. It is a great way to do a demo either 1 on 1 or as part of a team meeting.

However it does require a provisioned device to be physically present, making it less convenient for showcasing small updates, asking for feedback, ad hoc sharing of tidbits with the rest of the team.

You can now record and share a 10 second clip anywhere you can share a video.

What is Windmill?

approx. 1 1/2 minutes read

“I commit code quite frequently during the day.”

TL;DR Windmill monitors your master branch. You can utilise it every time you merge and push to master while you keep your existing development workflow on a feature branch.

The goal of Windmill is to establish a process that enables you to:

  • know when your app can no longer be released, give you the reasons that hold you back and provide you with feedback/support on how to resolve them.

e.g. build no longer compiles, distribution certificate has expired etc.

  • monitor the “quality” of your app through metrics and reports.

e.g. do tests pass? how many tests are there? what’s the code coverage?

  • see the “progress” of your app by providing you with an IPA that you can install on a device

e.g. does the “pull to refresh” feature look and feel as expected?

This, among others1, is the value that Windmill aims to provide you with.

Windmill is not meant to be used while practicing TDD, working on a feature branch or as a replacement to a continuous integration service2.

Windmill exists to monitor your master branch for release candidates. A candidate that you decide when to turn into a public release by evaluating what is in front of you.

diagram visualising the windmill process


  1. By operating in a process like this you are also confident you can release your app at a moment’s notice. 

  2. A service that monitors every feature branch, continuously merging into a master branch, promoting to a release without any human interaction in a large codebase and/or distributed team. 

Announcing Windmill

approx. 5 minutes read

Background

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

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

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.

comparison

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
  • a student
  • a teacher

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


  1. With Apple’s blessings by offering command line developer tools. 

  2. 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. 

  3. Windmill recognises that as a business grows, so does the complexity around delivering apps. As Windmill evolves, accessibility and ubiquity remain strong anchors.