<RubyGems + Bundler
For many, CocoaPods is the first introduction to dependency management in programming projects. A lot of ideas for CocoaPods came from similar projects ( for example RubyGems, Bundler, npm and Gradle).
Understanding Ruby dependency management is useful because it allows you to specify versions of CocoaPods or other gems and ensure all developers in your team have the exact same version. This guide is for people looking to ensure consistency in their team dependencies or for using un-released versions of CocoaPods.
RubyGems is a hosted ruby library service. It centralizes where you look for a library, and installing ruby libraries / apps.
You'll have seen
gem install xxx. These are installed into a central database of versions. If you imagine that CocoaPods
installs all libraries/frameworks into a System folder and they are linked at runtime, then you have the rough idea
of how RubyGems keeps all the gems.
The downside of this is that there is no way to ensure that a project needing a specific version of a library can use that, it would always use the latest version. So as a developer, you would be cautious installing a new version of a library because it would be used in every library / app. This is the problem bundler solves.
Bundler creates a consistent application environment for your application, by allowing you to specify the version of libraries.
We took this idea almost whole-sale for CocoaPods. You define a Gemfile that says what libraries you want to include, and can
optionally specify a version or range. You run
bundle install and it will generate a Gemfile.lock saying the exact version of
all of your libraries and then anyone else running
bundle install with that project gets the exact same versions.
<What is a Gemfile?
source 'https://rubygems.org' gem 'cocoapods' gem 'cocoapods-keys' gem 'fui', '~> 0.3.0' gem 'xcpretty' gem 'second_curtain', '~> 0.2.3' gem 'fastlane'
<Using CocoaPods with a Gemfile
With a Gemfile setup, you run
bundle install to install, or
bundle update to update within your Gemfile's constraints.
From here on in however, you will need to remember to run
bundle exec before any terminal commands that have come in via
bundler. Given that CocoaPods is included in the above this means any time you would write
pod XX YY you need to do
bundle exec pod XX YY.
Doing it without
bundle exec will bypass your Gemfile's specific versioning and will use the latest version of the library within RubyGems. This
could potentially be the exact same version, but it can often not. If you are including CocoaPods plugins then they may also not be ran.
This means you can be sure that foundational tooling for projects are versioned just like your personal libraries.
<Using master CocoaPods
Often in-between releases you may be interested in using a Gemfile to work with an unreleased version of CocoaPods. Due to the size of the project we try to release slowly when we're sure it won't break projects. Like with CocoaPods you can easily use master, or forks of your ruby project. Here is an example of a Gemfile using CocoaPods master.
source 'https://rubygems.org' gem 'cocoapods', :git => 'https://github.com/CocoaPods/CocoaPods.git' gem 'cocoapods-core', :git => 'https://github.com/CocoaPods/Core.git' gem 'xcodeproj', :git => 'https://github.com/CocoaPods/Xcodeproj.git' gem 'cocoapods-keys', :git => 'https://github.com/orta/cocoapods-keys.git' gem 'xcpretty' gem 'shenzhen' gem 'sbconstants'
bundle install will get the versions from master. As CocoaPods is multiple gems, you may have to include other dependencies like above.