Exclusive: building native iOS apps with RubyMotion

In 2007, software developer Laurent Sansonetti launched an open source software project called MacRuby. It aimed to build a Ruby interpreter on top of the Objective-C runtime, providing a seamless bridge between Ruby and OS X "Cocoa" ecosystem—and it succeeded. Now Sansonetti hopes to do something similar for iOS.

Sansonetti recently left his job at Apple-where he has worked for the past seven years-to found his own startup, dubbed HipByte. He announced his first product today, a new software development kit called RubyMotion that will open the door for developers to build native iOS applications with the Ruby programming language.

I've been testing RubyMotion since March, when Sansonetti gave me access to a private beta release. In this article, I’ll give you an exclusive hands-on introduction to RubyMotion and describe how it can be used to build software for iOS. The article includes the full source code of a simple iOS demo application I created that displays the top stories from reddit.

RubyMotion

RubyMotion is built on top of the same underlying Objective-C Ruby implementation that powers MacRuby, but it uses a new LLVM-based static compiler to convert Ruby code into tightly-optimized machine code. The RubyMotion compiler produces extremely efficient native applications that aren’t dogged by the performance limits and resource overhead that typically afflict Ruby code.

Installing the RubyMotion beta

Mobile applications built with RubyMotion run just as fast as equivalent Objective-C applications and use a comparable amount of hardware resources during execution. RubyMotion applications also conform with Apple’s App Store requirements. According to Sansonetti, some RubyMotion applications have already been accepted into the App Store after passing the review process.

The standard iOS APIs are available in RubyMotion applications, which means that all capabilities available to Objective-C developers on the iOS platform are also available to Ruby developers. Likewise, RubyMotion apps can match the look and feel of the rest of the platform because their user interfaces are built with the same standard UIKit widget set.

Developing software with RubyMotion

Instead of tying RubyMotion into Apple’s IDE, Sansonetti provides a command-line tool set that supports a more traditional Ruby development workflow. A motion command will generate a new project from a template, and the generated project stub will include an app folder for implementation code and a resource folder for graphical assets and other resources. Any .rb file that you put in the app folder will automatically get compiled into the finished application. You don’t use the require keyword at all in RubyMotion.

RubyMotion’s build process relies on the Rake tool, which should be familiar to most Ruby programmers. Build options are used to specify which frameworks to include, and to manage other aspects of application configuration. When you run rake from the command-line, it will compile your application and then execute it in the iOS simulator.

The terminal where you ran rake will give you a REPL that lets you use Ruby expressions to interactively manipulate your RubyMotion application while it is running. The ability to make live changes to widget properties and internal application data structures at runtime is extremely useful for testing and troubleshooting issues in an application.

Testing a reddit client that I built with RubyMotion

Testing an application in the simulator also works well. You can use build targets with Rake to deploy your application to a device or to generate an ipa package for distribution in the App Store. Due to code signing restrictions, you will need to be an Apple Developer Program subscriber in order to test your RubyMotion applications on an actual physical device.

When I tested RubyMotion on a 2011 MacBook Air, it took roughly five seconds to compile my simple reddit demo and launch it in the simulator. The compilation time isn’t too bad, but it can feel like a bit of a nuisance for Ruby developers who aren’t used to waiting between changes. In addition to the compiler, RubyMotion also comes with a standalone ruby command that can execute headless scripts in a RubyMotion environment.

The RubyMotion development workflow is comfortable. I write code in Vim and keep a terminal window open for running Rake when I need to test. The one downside—and it's significant—to avoiding Xcode is that developers who use RubyMotion will have to code their user interfaces by hand instead of using visual layout tools. This is especially problematic for developers who are new to iOS because constructing the user interfaces in code requires substantial knowledge of the UIKit APIs.

Sansonetti speaks

I raised the Xcode issue when I discussed RubyMotion with Sansonetti. He said that Xcode integration will eventually be implemented, but it’s not on the short-term roadmap.

Instead, he is building a set of Ruby libraries for programmatically defining iOS user interface layouts. These libraries will wrap the iOS UIKit APIs with high-level constructs that are more comfortable to use. The approach is similar to that used by the HotCocoa library for MacRuby, but with a higher level of abstraction.

“We are focusing on a set of high-level Ruby gems for RubyMotion. One of them is a thin layer on top of UIKit,” Sansonetti told me. “We chose to implement the layout system with a domain-specific language that works a bit like CSS, so Ruby developers should feel at home. Our idea is similar to Cocoa’s auto layout, which is based on an ASCII-like language, except that we can do better in Ruby. We believe that this is much better way of building UI than Interface Builder, since you can visually represent the UI in code.”

Instead of bundling those libraries with RubyMotion, he intends to publish them on GitHub under a permissive license. He thinks that RubyMotion adopters will start creating their own abstraction libraries with a variety of different styles. Application developers will have the option of using his or choosing third-party wrapper libraries if they prefer.

I asked Sansonetti about his relationship with the MacRuby project, which he started as an open source effort while at Apple, and how it will evolve now that he is focused on building RubyMotion. He explained that his desire to continue working on MacRuby was one of the factors that motivated him to leave Apple and launch his own company.

“As a senior engineer on the Core OS team at Apple, I created and led the MacRuby project, however, MacRuby was only one part of my responsibilities," he said. "As MacRuby was stable enough, it became clear that I would have to stop working on it. I didn’t want to leave the project and its amazing community, so I thought about it for quite some time and realized that creating a startup around RubyMotion would be the best thing to do; I would keep working on MacRuby and eventually make a living out of it.”

Although he temporarily stopped participating in MacRuby development during a six month transitional period after leaving Apple, he’s diving back into the project again and doesn’t intend to stop contributing. He is currently the only employee of his new company, but he intends to grow the team and “hire a couple MacRuby contributors later this year.”

Building RubyMotion by himself was a major technical undertaking. We asked him to describe some of the most difficult tasks that he encountered during development.

“The biggest challenges were the implementation of the static compiler and memory model, which are brand new in RubyMotion,” he told us. “Handling the ARM ABI and the device protocol was also quite challenging. And it took a lot of time to get the runtime performing well on the device.”

Sansonetti also offered some insight into how Ruby’s expressiveness and flexibility might improve developer productivity.

“One of the most important features is definitely the interactive environment that Rubyists take for granted but which is sadly missing on other platforms. Having the ability to try things out in real time is extremely useful when iterating or debugging an app,” he said. “Ruby is also a very concise and expressive language. An iOS app written in Ruby will contain significantly less lines of code than a comparable app written in Objective-C. Less code means a faster development cycle, less bugs, easier maintenance and therefore more time to play Skyrim.”