RubyMotion: Put your Dreams in Motion with Ruby


Published on

DevCon Tlv 2013, by Vitaly Kushner

Dreaming of having your own app in the AppStore but dont know Objective C?
RubyMotion makes your dreams come true! You can start building native apps for OS X and iOS using Ruby language today!
We will introduce the toolchain and workflow, discuss compatability with native APIs and libraries, and compare RubyMotion to other alternatives.

Published in: Technology
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

RubyMotion: Put your Dreams in Motion with Ruby

  1. 1. Put Your Dreams inMotionwith RubyVitaly Kushner@vkushnerMonday, June 24, 13
  2. 2. Vitaly Kushnerprogramming since middle 80sprofessionally since early 90sRails since 2005founded Astrails in 2008Monday, June 24, 13Hello everybody, my name is Vitaly Kushner. Im a co-founder of Astrails. A Ruby on Rails consulting company.For the last 8 years we’ve been building web applications using Ruby on Rails, but this is not what I’m going to talk abouttoday.For a while I didnt know what to talk about.
  3. 3. RailsMonday, June 24, 13Yet another Rails introduction?
  4. 4., June 24, 13Nah, everybody knows already that for most web applications Rails is the best tool for the job.I wanted something more interesting.So instead I decided to choose a topic that Im much less of an expert in, actually not an expert at all, butrather something that Im currently learning and very excited about.
  5. 5. Railsblog in 5 minutesMonday, June 24, 13In fact I’m as excited as I was back in 2005 when I saw for the first time the legendary "blog in5 min" Rails screencast.I remember when I saw it for the first time I decided right there that Rails will be theframework for my next web project.
  6. 6. New ToyshinyMonday, June 24, 13Recently I had a similar experience, and now I have a new shiny toy to play with.
  7. 7., June 24, 13So.. What am I going to talk about today?Those of you that payed attention to the conference program already know, for the rest it willbe a pleasant surprise ;)
  8. 8. RubyMotionMonday, June 24, 13We are going to talk about RubyMotion. What is it, why and when would you want to use itand when not, and how it compares to alternatives.
  9. 9. Purpose?Monday, June 24, 13But first Id like to talk about the purpose of this talk.We dont have much time, so we are not going to go into much technical details. But Ill bevery glad if at least some of you will come back to work or home and decide to tryRubyMotion for your next great…
  10. 10. I hate IDEsseriously, they are all crapMonday, June 24, 13For a long time I wanted to develop for iOS and OS X, and I even started to go through thetutorials a couple of times, but I got frustrated every time. I got spoiled by the rubyecosystem, toolset and development process. To the point that dealing with the archaic  IDE was too much of a pain and  in some ways reminded me of the bad days of my WindowsGUI programming.Google for Xcode sucks and you will find tens of thousands of people that agree with me.Whenever I tried to follow Xcode tutorials, at some stage Xcode would just freeze and refuseto continue. There is no need to bash Apple here though, the same shit happens with Eclipseand any other IDS  there is. They are just too big and complex to reliably work and allow meto understand exactly what they do. They impose workflow on you that you cant change tosuit your needs.So, frustrated, Ive put away the iOS tutorials for a while.And then I saw the RubyMotion screencast and I immediately felt the excitement thatreminded me of my first days of Rails.
  11. 11. What is RubyMotion?Monday, June 24, 13What is RubyMotion?
  12. 12. "RubyMotion is a revolutionary toolchainthat lets you quickly develop and testnative iOS and OS X applications foriPhone, iPad and Mac, all using theawesome Ruby language you know andlove."Monday, June 24, 13"RubyMotion is a revolutionary toolchain that lets you quickly develop and test native iOS andOS X applications for iPhone, iPad and Mac, all using the awesome Ruby language you knowand love."
  13. 13. Why RubyMotion?Monday, June 24, 13So why would you want to use RubyMotion instead of Objective C?There are several reasons, but there is no a single killer feature. Instead the whole approachto development and workflow is what makes RubyMotion so special. Its not the features, itshow it feels to build stuff with RubyMotion that makes the difference.That being said, there are features too:
  14. 14. RubyMonday, June 24, 13First of all it uses Ruby, which is a language that I love very much. The syntax is great andvery readable. the language is very powerful and allows you to do some very impressive feats.Looking at Cocoa documentation and Objective C tutorials, you will find a lot of boilerplateverbose code and archaic interfaces.And if there is something Ruby community is allergic to its unnecessary boilerplate. So, as youwould expect, many of the Cocoa APIs have idiomatic Ruby wrappers. They reduce the amountof code you need to write to use them by a whole lot.
  15. 15. Simpleand readableMonday, June 24, 13Another thing is that Ruby code is simpler and more readable as a whole. Objective C is a veryold language that also descends from C, so there is a lot of cruft that was accumulated.Apple is doing a great job of modernizing it lately, removing quite a bit of boilerplate codethat is no longer needed, but still, Objective C code is much less readable then Ruby, andthere is more of it. For example, in Objective C you need to declare interface for every class,even if you only use it in a single place. in Ruby you just write your class.
  16. 16. REPLRead Eval Print LoopMonday, June 24, 13Its hard to overstate the importance of Read-Eval-Print-Loop console (REPL). Its utility isimmediately obvious to anyone that programmed in a language that has it.When you use RubyMotion you get a REPL with tab completion just like regular rubys IRB. Youcan poke inside your running application and call methods on your running applicationobjects while application is running. This is very very cool and improves the speed ofdevelopment quite a bit. Instead of recompiling for every simple change you can tweak thingsfrom the console while the app is running until you are satisfied. Then you can incorporatethe changes into the source code.There is a special REPL feature in RubyMotion that allows you to Command-click any UIelement in the emulator and have it’s context made available in the running console, I’mgoing to show it to you later.One of the biggest thing about RubyMotion is that it achieves all those cool things withoutsacrificing performance. It compiles your application to the native code that runs as fast as ifyou were writing it in Objective C (with one caveat I’ll mention later).
  17. 17. workflowMonday, June 24, 13Another very important thing is the workflow.As I already said I hate IDEs. I spent quite a bit of time configuring my command line toolsand editor. RubyMotion allows me to continue to use the same tools I use for writing webapplications with Rails to develop applications for OS X and iOS. There are no configurationdialogs for the application, all is done through simple ruby configuration files just like inRails. There are no big xml files to sift through. And its trivial to see the difference betweenversions in source control.
  18. 18. rakeMonday, June 24, 13The whole workflow is built around Rake - rubys excellent build management tool.To compile and run app on the emulator you just type rake and it does the rest.
  19. 19. rubygemsMonday, June 24, 13Oh, and I can use Rubygems to manage your application libraries.
  20. 20. testingMonday, June 24, 13For various reasons most iOS developers do not use automated tests much. The tools exist,but they are not as pervasive and advanced as in the Ruby land. And RubyMotion comes withan Rspec like testing and UI automation framework that you can use to test your applications.No more mindless clicking to test the most basic flows. You will of course still need toactually use the app, but a lot of functionality can be tested by the framework, without humanintervention.
  21. 21. communityMonday, June 24, 13In addition to already huge Objective C community, there is a new and growing RubyMotioncommunity. And Ruby developers are known to produce some pretty innovative libraries andtools.
  22. 22. JoyBoxhttp://joybox.ioMonday, June 24, 13For example, there is a library called JoyBox (, which is a game wrapper forRubyMotion. I suggest you find a JoyBox REPL demo video on Vimeo. its amazing how you cando very impressive things with just a line of ruby.
  23. 23. • write less code• use better tools• have more funMonday, June 24, 13Did I mention that its actually a lot of fun programming in RybyMotion? ;)
  24. 24. downsides?Monday, June 24, 13Are there any downsides to this?
  25. 25. YESof courseMonday, June 24, 13Yes, of course. Just as with most everything in life, there are tradeoffs.
  26. 26. expensive shit$200Monday, June 24, 13First of all this shit is expensive. $200 a piece expensive.
  27. 27., June 24, 13Its a commercial product. While most of the toolchain and workflow tools are open source thecompiler itself is the secret souse and it costs money.So this kind of puts it out of the I just want to fool with it category. On the other hand Appledevelopers already pay to $100 to Apple for the access to the development platform, so thisisnt a big deal. In any kind of commercial environment, the benefits of RubyMotion will payfor its price many times over.
  28. 28. downsides?• expensive• no low level data access• no static checks during compilationMonday, June 24, 13Second, Ruby doesnt give you low level bit access to the native memory, like C does. so if youare writing a 3D game with lots of graphics processing, RubyMotion might not be a good fit.2D games are perfectly OK though (see JoyBox).That being said, RubyMotion can call any function available from Objective-C. So you canlocalize your hard-core data processing into a simple Objective-C lib, then drive it with therest of the UI from RubyMotion.Also, as with all dynamic languages, you loose static type checks by compiler. if you have atypo in a variable name you will find out at runtime, not during compilation.
  29. 29. AlternativesPhonegap, TitaniumMonday, June 24, 13We of course cant ignore the alternatives, so Id like to dedicate a bit of time to discuss them.There were other solutions available, like Phonegap and Titanium.
  30. 30. multi-platformMonday, June 24, 13The big selling point for those is that they are multi platform. So that you can theoreticallyreuse a lot of the code to support both iOS and Android platforms
  31. 31. HTML/JSMonday, June 24, 13Another thing is that you can use simple HTML and Javascript to develop your applications.
  32. 32. slowMonday, June 24, 13
  33. 33. No native API accessMonday, June 24, 13But those very same benefits are also the biggest downside. You do not talk directly to yourruntime, you talk to the library which in turns talks to the OS. So if some API call is notsupported by the wrapper, you dont get to call it. Also, while HTML/JS is a viable solution formany applications, it is very limiting in what you can do. Where RubyMotion can accommodateall but the most graphics and data intensive applications like 3D games, html/js apps simplycant deliver the same slick UI you might want to implement for your native application.Its really easy to develop applications for those platforms because the APIs are much simplerthen the native ones, but it just means that you have much less APIs to work with. Lots ofthings are impossible to do.
  34. 34. RubyMotion is NativeMonday, June 24, 13RubyMotion on the other hand has all the native APIs.While it wraps some of the APIs into idiomatic Ruby interfaces It also makes all of ApplesAPIs available.For example, if Apple releases NFC API tomorrow you can start using it the same day, youdont need to wait until some 3rd party provides you with a wrapper. You can wrap it withidiomatic Ruby yourself, or just go and use the API directly. Your choice.
  35. 35. RubyMotion is FASTMonday, June 24, 13As I already mentioned RubyMotion is fast. Almost as fast as Objective C. IT compiles yourRuby code to native executable.How does it do it? Its quite ingenious in fact. And its only possible because Objective C andRuby are very similar in many respects. They both descend from Smalltalk and it shows.
  36. 36. smalltalkMonday, June 24, 13The message dispatch is quite similar in semantics, so that RubyMotion implements Rubysyntax by using native ObjectiveC internals.
  37. 37. RubyMotion != RubyMonday, June 24, 13Its important to understand though that RubyMotion is not Ruby.
  38. 38. no evalMonday, June 24, 13Some parts of ruby are made unavailable. For example, there is no eval, but that has more todo with Apples AppStore guidelines then with technical limitations. Also there is no require,but well get to this a bit later.
  39. 39. named parametersMonday, June 24, 13Some of the syntax was changed to support platform features. For example, Objective C codeuses named parameters. And in Ruby they are only available since Ruby 2.0. RubyMotionchanged ruby syntax to support named parameters from the beginning.
  40. 40. ## Objective CNSError *error = nil;NSData *data = [[NSData alloc]initWithContentsOfFile: answerFile,options: NSDataReadingUncached,error: &error];# Same in Rubyerror = = NSData.alloc.initWithContentsOfFile(answerFile,options:NSDataReadingUncached,error: error)# Dereferencing errordo_something_with_error error[0]Monday, June 24, 13To show you an example, here is a typical Objective C call that constructs an NSData objectfrom a content of a file:Two things to note here: use of error pointer and named arguments.To support this frequently used ObjectiveC idiom of error pointer RubyMotion introducesPointer class, which encapsulates the functionality, and lets you de-reference the pointerusing ruby array syntax.we can dereference the error pointer using array syntax.
  41. 41. blocksMonday, June 24, 13It is actually quite remarkable how little changes had to be done to Ruby syntax to allownative Objective C interface support. There is another cool Objective C feature that directlymaps into ruby: blocks.
  42. 42. # block in Objective C[UIView animateWithDuration: 1.0animations: ^{@label.alpha = 1}];# block in RubyUIView.animateWithDuration(1.0,animations: ->{@label.alpha = 1})Monday, June 24, 13Lets see another typical Objective C code snippet. This time we animate a text label:This is very similar to Ruby blocks, just a bit different syntax.As you can see it is quite trivial to translate Objective C code into Ruby. Thats why you dont need special adopted documentation. You can just use the regular APIdocs and translate the syntax to ruby on the fly.That being said, RubyMotion comes with lots of Apple API docs translated and accessible toRubyMotion version of Ruby "ri" documentation reader.
  43. 43. magicMonday, June 24, 13But enough of talking, lets see how the magic happens.We will create a very simple iOS application. Creating a hello world is trivial, but that would betoo boring, so we will do something a little more interesting. We will create an app that findsout your current GPS location, and then requests weather information about the location.
  44. 44. Monday, June 24, 13This is the screenshot of its running.
  45. 45. > motion create weatherCreate weatherCreate weather/.gitignoreCreate weather/app/app_delegate.rbCreate weather/RakefileCreate weather/resources/Default-568h@2x.pngCreate weather/spec/main_spec.rbMonday, June 24, 13Note: since we dont have much time I wont explain every little detail.When you install RubyMotion you get the motion command line tool that does most of thework.To create a new application you just write motion create AppName.As you can see, just like Rails, RubyMotion creates a skeleton application with some basictests.Lets review the files.
  46. 46. > cat Rakefile# -*- coding: utf-8 -*-$:.unshift("/Library/RubyMotion/lib")require motion/project/template/iosMotion::Project::App.setup do |app|# Use `rake config to see complete project = weatherendMonday, June 24, 13Rakefile contains the application configuration block. You can see what configuration optionsare available by running rake config.
  47. 47. > rake configbackground_modes : []build_dir : "./build"codesign_certificate : "Error"delegate_class : "AppDelegate"deployment_target : "6.1"device_family : :iphoneentitlements : {}files : ["./app/app_delegate.rb"]fonts : []framework_search_paths : []frameworks : ["UIKit", "Foundation", "CoreGraphics"]icons : []identifier : ""interface_orientations : [:portrait, :landscape_left, :landscape_right]libs : []...Monday, June 24, 13
  48. 48. > rake -Trake archive # Create an .ipa archiverake archive:distribution # Create an .ipa archive for distribution (AppStore)rake build # Build everythingrake build:device # Build the device versionrake build:simulator # Build the simulator versionrake clean # Clear build objectsrake config # Show project configrake ctags # Generate ctagsrake default # Build the project, then run the simulatorrake device # Deploy on the devicerake simulator # Run the simulatorrake spec # Same as spec:simulatorrake spec:device # Run the test/spec suite on the devicerake spec:simulator # Run the test/spec suite on the simulatorrake static # Create a .a static libraryMonday, June 24, 13You can see other commands by running rake -T:I suggest you always run rake crags to build tags run the app you just run rake.
  49. 49. > rake configbackground_modes : []build_dir : "./build"codesign_certificate : "Error"delegate_class : "AppDelegate"deployment_target : "6.1"device_family : :iphoneentitlements : {}files : ["./app/app_delegate.rb"]fonts : []framework_search_paths : []frameworks : ["UIKit", "Foundation", "CoreGraphics"]icons : []identifier : ""interface_orientations : [:portrait, :landscape_left, :landscape_right]libs : []...Monday, June 24, 13“delegate_class” config is site to “AppDelegate” by default. This is the name of the class thatwill be instantiated by the environment and receive lifecycle callbacks.
  50. 50. # app/app_delegate.rbclass AppDelegatedef application(application, didFinishLaunchingWithOptions:launchOptions)trueendendMonday, June 24, 13Lets check out the AppDelagate class. It is placed in “app/app_delegate.rb”.As you can see it doesnt do anything yet.
  51. 51. > rake configbackground_modes : []build_dir : "./build"codesign_certificate : "Error"delegate_class : "AppDelegate"deployment_target : "6.1"device_family : :iphoneentitlements : {}files : ["./app/app_delegate.rb"]fonts : []framework_search_paths : []frameworks : ["UIKit", "Foundation", "CoreGraphics"]icons : []identifier : ""interface_orientations : [:portrait, :landscape_left, :landscape_right]libs : []...Monday, June 24, 13Another thing in config is “icons”. It is blank by default. Lets change it.
  52. 52. # copy icon file into resources directory> cp ../icon.png resources# add icon filename to app.icons in Rakefileapp.icons << icon.pngMonday, June 24, 13We need to copy the icon png file into the resources directory.
  53. 53. Monday, June 24, 13As you can see our app has a custom icon now.
  54. 54. def application(application,didFinishLaunchingWithOptions:launchOptions)@window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)@window.backgroundColor = UIColor.lightGrayColor@window.makeKeyAndVisibletrueendMonday, June 24, 13Now lets change the applicaiton’s background color to light gray.
  55. 55. class AppDelegatedef application(application,didFinishLaunchingWithOptions:launchOptions)@window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)@window.backgroundColor = UIColor.lightGrayColor@window.rootViewController = WeatherController.alloc.init@window.makeKeyAndVisibletrueendend# app/weather_controller.rbclass WeatherController < UIViewControllerdef viewDidLoad@label = UILabel.alloc.initWithFrame([[10, 10], [300, 50]])@label.text = "DevCon 2013"@label.textColor = UIColor.darkGrayColor@label.backgroundColor = UIColor.orangeColor@label.textAlignment = UITextAlignmentCenterview.addSubview @labelendendMonday, June 24, 13Cocoa is an MVC framework, so now we need a controller. we will put it into app/weather_controller.rb:We inherit from UIViewController. It will create a view for us by default, and viewDidLoadmethod will be called once the view is loaded.Here we can initialize the rest of the application. Lets add a tex label.
  56. 56. def viewDidLoad@label = setup_label [[10, 10], [300, 50]], UIColor.orangeColor@label.text = "DevCon 2013"enddef setup_label frame, bgcolorlabel = UILabel.alloc.initWithFrame(frame)label.textColor = UIColor.darkGrayColorlabel.backgroundColor = bgcolorlabel.textAlignment = UITextAlignmentCenterview.addSubview labellabelendMonday, June 24, 13Lets refactor it a bit to prepare for multiple labels that we need.
  57. 57. @name_label = setup_label [[10, 10], [300, 50]], UIColor.orangeColor@place_label = setup_label [[10, 80], [300, 50]], UIColor.yellowColor@temp_label = setup_label [[10, 150], [300, 50]], UIColor.greenColorMonday, June 24, 13Here you can see we created 3 labels of different colors.
  58. 58. Bubble Wraphttp://bubblewrap.iohttp://rubymotion-wrappers.comMonday, June 24, 13So far we used Objective-C API as is, which is not very ruby like. Lets see how better can it beby using idiomatic Ruby.RubyMotion has quite a bit of “wrappers” available. Ruby libraries that provide a more ruby-like interface to common APIs.You can find many wrappers on and simply on github.BubbleWrap ( is one of the basic ones. it wraps Cocoa Touch into niceruby APIs.
  59. 59. # Gemfilesource https://rubygems.orggem rakegem bubble-wrap# Rakefilerequire bundlerBundler.requirerequire bubble-wrap/allMonday, June 24, 13As mentioned before, RubyMotion doesn’t have “require” support.So instead of requiring your libraries from your RubyMotion code, you do it in your Rakefile,where it becomes the part of the build.We will of course use Rubygems and Bundler to manage our libraries.
  60. 60. @name_label = setup_label [[10, 10], [300, 50]], orange@place_label = setup_label [[10, 80], [300, 50]], yellow@temp_label = setup_label [[10, 150], [300, 50]], greenlabel.textColor = dark_gray.to_colorlabel.backgroundColor = bgcolor.to_colorMonday, June 24, 13Now we can use some ruby goodies. First lest try something simple, like String#to_color.
  61. 61. def viewDidLoad...get_locationenddef get_locationBW::Location.get_once do |loc|puts loc.inspectendendMonday, June 24, 13But that is not what we added BubbleWrap for.Lets try the Location services. Using natie API that would be a screenful of code. UsingBubbleWrap its a one liner.You can see that the application now asks for permission to access location data.
  62. 62. def get_locationBW::Location.get_once do |loc|get_weather loc.latitude, loc.longitudeendenddef get_weather lat, lonBW::HTTP.get("{lat}&lon=#{lon}") do |res|puts res.inspectendendMonday, June 24, 13Now that we have location we can fetch weather information. We will API for that.And we will use bubble-wrap HTTP wrapper to fetch it.
  63. 63. def get_weather lat, lon...update_weather res.body.to_str...enddef update_weather jsonres = BW::JSON.parse(json)name = res[name]weather = res[weather][0][description]temp = res[main][temp] - 273.15@place_label.text = name@weather_label.text = weather@temp_label.text = "%f.2" % tempendMonday, June 24, 13Now that we have the weather json response, lets parse it and update our labels with theinformation.Note that even such a simple thing as JSON parse would be much more verbose withoutBubbleWrap.
  64. 64. •••, June 24, 13For the end a couple of useful resources for you to learn RubyMotion.The official blog is something that you will want to follow whendeveloping with RubyMotion. is a nice place to start. is the “things to do/read to lean” list forRubyMotion from ThoughtBot.
  65. 65. Thank you!Slides and video will be published at Kushner@vkushnerMonday, June 24, 13As mentioned before the slides and the video will be posted on our blog at me on twitter (@vkusher) to be notified about new presentations, updates to “The Rails4 Way” book that I co-authored with Obie Fernandez and our open source libraries.