Ever dreamt of faster Xcode builds?

Reading Time: 3 minutes

We have.

Everli iOS apps get new amazing features every week, constantly growing bigger and more complex, this makes Xcode build times grow proportionally.

Of course, one solution might be to regularly update your hardware, but here we’re going to talk about a free software alternative to that. In the Everli iOS team, we decided to give PodBuilder a spin, and we did right.

If you use CocoaPods to add libraries to your project, you may have noticed that Xcode build times get longer for every dependency you add. In most cases, Pod libraries are just source code that gets added to your project’s workspace. And unfortunately, Xcode seems to like analyzing and recompiling pod libraries very often, even if those files are rarely modified (most likely only when updating).

PodBuilder is a complementary tool to CocoaPods that does one simple smart thing: precompiling your project’s Pods libraries (once). So instead of adding Pod source code to your project, you add its compiled (binary) version. Adopting this amazing tool brings some clear advantages:

  • Xcode will not recompile your Pod libraries’ source code because… there’s no source code 🙂
  • SourceKit has much less code to index and analyze.

On large projects, precompiling Pod libraries can translate into a ~50% reduction of build time, allowing for a much better Xcode experience. In our specific case that’s exactly what we were able to achieve. Here are our test results.

1. using standard Pod libraries
2. using PodBuilder precompiled libraries

As you can easily see from the screenshots above, we were able to halve our build times for our Customer App.

And we got even more amazing results on our Shopper App. Check these logs:

1. using standard Pod libraries
2. using PodBuilder precompiled libraries

Of course, your experience may vary, depending on the structure and the size of your project, but if you have a lot of Pods and you’re tired of waiting for Xcode, then PodBuilder may be well worth a try.

PodBuilder is a Ruby script and can be easily installed via RubyGems package manager. Using it is even more straightforward, just follow the docs here. The only “effort” required is to learn some new commands and get familiar with a couple of new files to manage the libraries. The main changes after switching to PodBuilder:

  • the original Podfile is copied to PodBuilder/Podfile. This must be used as the new master file to manage the libraries
  • the original Podfile should not be changed manually anymore, it’s autogenerated by PodBuilder and filled with the correct references to prebuilt files.
  • PodBuilder/Podfile.restore is PodBuilder’s “lock” file, used to pin library versions so as to be able to check out a project exactly as it was at a specific moment in time. Autogenerated, not to be touched.

There are PodBuilder commands to do almost anything: prebuild, restore, and even switching libraries between the standard and the prebuilt version. Unfortunately not all libraries play nice when precompiled, in these (few) cases PodBuilder offers a configuration file (PodBuilder.json) with some advanced customization possibilities, among which a “blacklist” of pods not to be prebuilt. So yes, PodBuilder allows for projects using a mix of source code and precompiled libraries. Even in these mixed cases, you will manage your libraries via PodBuilder (no, you don’t need to run the original “pod” command separately).

From our experience the only (very small) downside of having prebuilt libraries is that they of course take more space than source code, considering also that PodBuilder prebuilds for all platforms (to be able to run both on physical devices and simulators). If you push your libraries to GitHub then maybe you want to consider moving prebuilt libraries to LFS.

Drop a few lines to tell us about your experience with PodBuilder. Happy building!

Author: @emidal
Thanks to: @arpit for contributing with additional benchmarks
Image source: unsplash.com

Leave a Reply

Your email address will not be published.