Dependency Managers

We're getting close to actual software engineering. However, there is one more thing that we will need to set up - Dependency Managers. Let's figure out what dependencies are.

Software development is a pretty routine process. All apps have lots of similar functions, from user authentication, requests to remote servers, to swipable cells and side menus.

In order not to reinvent the wheel, developers use third-party libraries. It is reusable code, that has been written once, and can be used in other projects if library's license allows it.

For example applications with Facebook/Twitter login. I'm sure you have seen a lot of them: user opens the app, and it wants him to log in with his email, his Facebook account, Twitter account, or any other social account user may have. In this example authentication is a process that can be reused - it will be the same on all devices, and for all users. So why write the same code more than once?

Most dependencies (libraries) are open sourced - it means you can get its source code, read it, make sure it works as you expect, etc. Even more - if a library does not have some essential features, or you have found a bug in it, you can always send a fix to its author, or you can make your branch that contains a fix.

There are hundreds of dependency managers, but we need to use only those, that were developed for the programming language that we use.

In Rubymotion we will use two dependency managers:

It is important to install both of them because we will heavily use them during development. Fortunately, both are very easy to install, and you can do it with next commands:

gem install bundler
gem install cocoapods

As you can see, you have used "gem" command here - both utilities are just Ruby gems.

Bundler

The central part of a bundler is Gemfile - a text file that creates automatically with all Rubymotion projects. You just need to list all dependencies that you would like to use in your project and run a command in your terminal: bundle install

All third-party libraries that you will use are maintained by other people, and they often get updated: bug fixes, new features, etc. Therefore, it is a good idea to specify a version of each library that you are going to use. Here is an example of an average Gemfile:

As you can see, Gemfile is pretty straightforward. First two lines are sources where Bundler will look for gems. All next lines tell Bunlder, which gems you are going to use during development. In a "group" blocks you can list gems that need to be installed only for specific tasks, for example, gems in "development" group are used only during development. You can read more about Bundler on its homepage

Sometimes you will need to update your gems. In this case, bundle update command will help you.

Cocoapods

Even though gems may seem enough for Rubymotion development, we are going to use Cocoapods too. There were lots awesome libraries written before Rubymotion, and it would be a good idea to use them in a project as well.

In Rubymotion Cocoapods specified in the Rakefile. Rubymotion creates this file for you every time you create a new project, just like the Gemfile. However its structure is very different - the main purpose of a Rakefile in Rubymotion is an application configuration. All pods are described in a small app.pods block, and it usually looks like this:

To install pods, in Rubymotion, just use rake pod:install command. Or rake pod:update to update installed cocoapods.

Version Specifiers

Both previous screenshots had statically specified versions. It means code like gem "library", "1.0.1" will tell bundler to install "library" with a version not higher, and not lower than "1.0.1". But sometimes you may want to allow Bundler or Cocoapods to keep updating the library if updates have only bug fixes and small improvement.

Let's talk about version numbers in software for a minute. There are major numbers, minor numbers, and patch numbers in versioning. In "1.2.5", the first number, "1" is the major number. It is usually increased with some significant updates, and unfortunately, these updates sometimes are not backwards-compatible, which means your old code would need an update as well.

The second number, in our example it is "2", is a minor version number. Minor updates usually have some small changes in functionality. According to Semantic Versioning, it should be safe to install minor updates, because they all should be backwards-compatible. Unfortunately, it is not always true, and sometimes even minor updates may break your code, so be careful, and write tests.

The third number is a patch number. Updates that have patch number increased usually have only some bug fixes, so in most cases it is safe (and is a good idea) to update to each new version with higher patch number.

Now we can go back to our version specificators in Gemfiles and Rakefiles. As you already know, you can specify exact versions for each library. But Bundler and Cocoapods can be more flexible:

gem "library", ">=1.0.0"
will install any version that is higher or equals "1.0.0".
gem "library", "~>1.0.4"
will install any version that is higher or equals "1.0.4", and lower than "1.1". (update only to next patch number)
gem "library", "~>1.1"
will install any version that is higher or equals "1.1.0", and lower than "2.0". (update to next minor and patch numbers)

Our environment is almost ready! We just need to install one more thing - Rubymotion.

Book Index | Next