Bundler is a best friend of iOS developer

Petro Korienev 🇺🇦
5 min readJun 7, 2018

--

IMPORTANT: SUPPORT UKRAINE NOW 🇺🇦

Please, spend few minutes reading through the website:

https://supportukrainenow.org/

Your help can save lives today!

This is an article #2 of “It’s all about Tools” cycle. So,

Abstract

Bundler is a simple and powerful dependency manager for Ruby gems. Wait, why Ruby, the title says “iOS developer”? The answer is simple — two of most popular iOS development tools (cocoapods and fastlane) are written almost entirely in ruby and are distributed as Ruby gems. While you might not use fastlane yet, you’ve definitely heard about cocoapods and I’m 99,99% sure use it (or used it, but stopped in favour of Carthage) in your development process.

So, let me tell you few stories about mentioned gems…

Story 1

I recently realized that I have a real mess of XCode playgrounds on my machine:

Some of them are Swift standalone, another ones have to be embedded into XCode project because they should play with 3d-party libraries like Alamofire, ReactiveSwift or so. I decided to create a single XCode project for the purpose, “PlaygroundsHost”, fill it up with most wide-spread pods I’m using and slowly move all playgrounds into that project to keep them in single place. The flow of integrating 3d-party library into playground is simple:

  1. Create a new project. Close it.
  2. Create a Podfile in a root folder. Fill it with necessary pods (ex. Alamofire)
  3. run pod install
  4. run open *.xcworkspace to open freshly created workspace
  5. Create a new Playground, place it somewhere inside project folder (in my case it was $PROJECT_DIR/Playgrounds/MyPlayground.playground)
  6. Drag created Playground into XCode.You’ll see something like this:
  7. Cmd+B to build all Pods and project
  8. You’re done, you can now use import Alamofire in a playground.

Your XCode Project Navigator tab looks like this:

Well, I did it and…

error: Couldn’t lookup symbols: __T09Alamofire7requestAA11DataRequestCAA14URLConvertible_p_AA10HTTPMethodO6methods10DictionaryVySSypGSg10parametersAA17ParameterEncoding_p8encodingAJyS2SGSg7headerstFfA3_

I was quite confused and tried to google issues, and found that something is broken in playgrounds integration between cocoapods 1.4.0 and 1.5.0. My local version was 1.5.2. Can one downgrade a version of cocoapods to certain release? Definitely yes. Does it worth playing with versions up and down all the time you switch between project? Definitely no…

Story 2

My fellow developer asked me few days ago whether I faced a weird issue he’s struggling right now — on CI build while exporting an archive he had a build failure on “Lottie.framework does not support provisioning profiles.”

We chatted a bit and guessed that the issue might be related to cocoapods update and their Copy Frameworks build phase.

OTOH he had everything working smoothly with cocoapods 1.5.3 running on a local machine. However, he wasn’t able to do an archive, because code-signing identities were located on a remote CI machine. Also he didn’t have remote access to change remote versions of cocoapods, like I had in story 1.

It was too late in the night to contact a maintenance engineer who had ssh to CI worker machine…

Story 3

About a year ago, I also had an issue with CI archive build. We ran on a big TeamCity cluster with few workers and I suddenly realized that all the time build is run on a random worker machine from a given pool in a bit different environment — cocoapods version, fastlane version… It was fine, until some transporter issues arised when submitting a build to ITunesConnect.

I didn’t have certs and provisions locally either so my best try was google and I’ve found that my issue was fixed few days ago in latest fastlane. How to update fastlane on a remote without ssh/vnc? Well…

Here comes bundler

Integrating bundler into your development/deployment workflow is simple as ABC:

A. Create a Gemfile in your project’s root folder. Fill it with stuff like:

# frozen_string_literal: true
source "https://rubygems.org"
gem "cocoapods", "1.4.0"

B. Save it and run bundle install . Bundler will generate Gemfile.lock, whose purpose is pretty similar to Podfile.lock in cocoapods universe. Actually, Podfile / Podfile.lock and the whole cocoapods concept was strongly inspired by bundler and rubygems, so historically they were in place even earlier

C. From now on, use command bundle exec pod install and not just pod install

What do you get in exchange of two more files in a root folder and two more words in a command line?

  1. Consistency across all your environments — development, staging, production, whatever more you have. Bundler gives your a guarantee, that software that worked on your environment will work on remote environment sharing the same Gemfile and Gemfile.lock (so in case it’s not yet obvious commit them to your version control)
  2. Easy versions change. Playgrounds not working with cocoapods 1.5.2?
    gem "cocoapods", "1.4.0", bundle install, bundle exec pod install, Cmd+B
    Wanna check whether project works on cocoapods-prerelease? gem "cocoapods", "1.5.0.beta.1". Issue arised on a latest fastlane? gem "fastlane", "2.94.0"
  3. In advance to p.1, you and your project fellows stop fighting pod install diffs from different cocoapods versions, just because you share Gemfile / Gemfile.lock and have the same development environment.
No more weird diffs after pod install

With the simply configurable and easy-to-use tool you now control the versions, not they control you.

There are also few other benefits of using explicit versioning, like

  • Visibility of version changes across the team. Whoever updates, it is done explicitly for a reason, and others review the change
  • Reasonable version changes → better control over 3d-party codebase, because developers would need to study changelog / release notes before the update

Few summary thoughts and further reading

In software development versioning is one of the most important concept, often overlooked even by engineers with decent seniority level. If you want feel safer and produce more reliable and stable software, please pay more attention to dependencies and versions.

Topics covered in this essay are not new knowledge of any kind, it’s discussed by https://guides.cocoapods.org/using/a-gemfile.html, https://docs.fastlane.tools/getting-started/ios/setup/#use-a-gemfile. Also there’s a good try of creating wiki project, covering versioning for iOS apps as well by Felix Krause here: https://ios-factor.com/dependencies — it definitely worth to take a look at.

I’m done now, thanks for reading this out. Hope you’ll enjoy your development life with bundler!

P.S. All three stories I’ve mentioned were solved quickly with the help of bundler.

--

--