How Hannibal was finally defeated by Cupertino: From GYP to SPM

Gabriel Massana
poq-techblog
Published in
4 min readJun 8, 2021

At poq we build native commerce applications for some of the best brands in the world.

Before my time at poq, I knew about Jenkins as a Continuous Integration tool and about Cocoapods as a dependency manager. Nothing else really.

Around four years and a half ago, poq developers were working on different clients’ native mobile app projects in a single and monolithic Git repository. The unique repository had an interminable list of targets; one per test environment per client; and relied on Cocoapods for a number of dependencies. It was chaotic, as you can imagine.

A few days before I joined poq, our developers decided it was time to separate the client code infecting this monolith. This resulted in the birth of the poq Platform framework, which allowed each client to own and maintain their own Git repository. This was a step in a better direction. But, to make this work, we needed to introduce some tooling to allow clients to easily consume the platform and it’s Cocoapods dependencies.

This is how I was introduced to Generate Your Project (GYP), a Google tool for generating an Xcode Project using a config file containing the rules and the targets needed for each project. This way, the project file could be removed from version control, eliminating the common merge conflicts that were previously caused by such a large team.

Although this was totally new for me, I became used to running terminal commands to generate the project each time a checkout was done. The command was regenerating .xcodeproj and .xcworkspace, and everyone was happy.

The problem with GYP was that it was not well maintained. The developer who set it up actually created a GitHub repository and copied in the whole of the GYP python project to fix multiple issues with generating targets. Developer documentation was limited and the GYP community was forced to use Google groups. It was not easy to work with, but at the time there were few alternatives.

Then, XcodeGen came to the rescue! This is a similar tool to GYP. However, unlike GYP, it is maintained and is super user-friendly when you need to generate your project file. Instead of the frustrating gyp file formats, we were able to use yaml or json. This was a great change in our lives! Now it was easy to maintain and update.

So, the generation of project files was solved. Let’s talk about compile times. Every time we were generating a project, or changing some values in the app, several minutes were required to rebuild the project. Sometimes a simple UI change could consume your evening. No kidding!

You’ve probably heard about Hannibal, the Carthaginian general who tried to conquer Rome with elephants, right? Okay. So, to avoid the growing building times we introduced Carthage and Rome.

Carthage is a tool to manage dependencies, like Cocoapods. The good thing was that it was able to shorten the compiling time due to precompiling the frameworks.

However, two bad things were also introduced. Let me explain: we can work with several projects every day and each probably uses different versions for their dependencies. This means the benefit of Carthage was not that good, as it needed to create the binary files every time we were generating the project anyway.

So, Rome came to the rescue of Carthage. Ironic, right? Rome is a tool that allows to cache Carthage binaries. This means, if I’m the first one to build a framework for version 1, I’ll be the only one suffering the compile time for this version. The rest of the team will use the cached version. Nice, right?

As said before, Carthage wasn’t all greener pastures. We had our fair share of cache and dependency issues. The worst of which was our second problem: losing the ability to properly debug, where the results of ‘po’ were either random or an error. We’d been suffering from this lack of proper debugging capability for quite some time.

Eventually the Swift and Apple community came to the rescue with the Xcode integrated release of Swift Package Manager (SPM). So, a few months ago, we started to use SPM. XcodeGen works perfectly with SPM, so no new tool to generate the projects was required. Now we can debug again without problem. We can say that compiling time is still small. Also, if you’ve already tried SPM, you know how nice it looks in Xcode.

Let me finally recognize the two devs that made all of this possible: Nikolay Dzhulay was the one that added GYP and started poq on this journey, while Joshua White, our current iOS Tech Lead, has been improving the tooling since GYP times.

Ohhhhhhh! What about Cocoapods, I hear you ask? Yes, we still use Cocoapods, as some frameworks and integrations do not support SPM… yet.

--

--

Gabriel Massana
poq-techblog

Computer Engineer. iOS Team Lead at Poq (London). Ex-photographer at @elpuntavui (Barcelona)