RubyMotion is a toolkit that allows you to write native iOS applications using Ruby. Normally I'm pretty skeptical of these alternative frameworks, but RubyMotion is actually quite interesting. In this episode I build a small application and talk about the pros & cons of using the toolkit.
Links Episode Source Code RubyMotion site RubyMotion Examples BubbleWrap Library Creating a project RubyMotion comes with a binary for creating new projects. Just type motion create <projectname> to start a new project. The project will contain an app folder and an app_delegate.rb with almost nothing in it. To get started, you'll want to create a window: class AppDelegate def application(application, didFinishLaunchingWithOptions:launchOptions) @window = UIWindow.alloc.initWithFrame UIScreen.mainScreen.bounds @window.makeKeyAndVisible true end end Creating a view controller You are free to create your classes wherever you like, however I like to have some basic structure, so I create a folder view_controllers and place a new file, episodes_view_controller.rb inside. class EpisodesViewController < UITableViewController def init super.initWithStyle(UITableViewStylePlain) end def viewDidLoad super self.title = "Episodes" @episodes ||= [] end end Now, in the app_delegate.rb, you just need to instantiate & show this view controller: class AppDelegate def application(application, didFinishLaunchingWithOptions:launchOptions) @window = UIWindow.alloc.initWithFrame UIScreen.mainScreen.bounds <strong>evc = EpisodesViewController.alloc.init nav = UINavigationController.alloc.initWithRootViewController evc</strong> @window.rootViewController = nav @window.makeKeyAndVisible true end end Now, just type rake to run your application. Adding a Gem Next, create a Gemfile that looks like the following: source :rubygems gem 'bubble-wrap' Run bundle install, then open up the Rakefile to add the require statements we need to bring in the library: require 'motion/project' <strong>require 'bubble-wrap/core' require bubble-wrap/http'</strong> ... Creating the Model Create a folder for models and place a new file called episode.rb inside. The models are plain ruby classes. class Episode attr_accessor :title def initialize(attrs) attrs.each_pair do |key, value| self.send("#{key}=", value) end end def self.from_json(json) new(:title => json["title"]) end end Here we added some code for easy initialization and json parsing. Talking to the API Next, let's create a folder for our api related classes and place api_client.rb inside. class ApiClient def self.fetch_episodes(&block) BubbleWrap::HTTP.get("http://nsscreencast.com/api/episodes.json") do |response| if response.ok? json = BubbleWrap::JSON.parse(response.body) episodes = json.map {|ej| Episode.from_json(ej["episode"])} block.call(true, episodes) else block.call(false, nil) end end end end Tying it all together Now we just need to use the APIClient class to fetch the episodes and render table view rows: class EpisodesViewController < UITableViewController def init super.initWithStyle(UITableViewStylePlain) end def viewDidLoad super self.title = "Episodes" @episodes ||= [] <strong> ApiClient.fetch_episodes do |success, episodes| if success @episodes = episodes p "Received #{@episodes.length} episodes" self.tableView.reloadData else App.alert("Oops!") end end</strong> end <strong> def tableView(tableView, numberOfRowsInSection:section) @episodes.count end def tableView(tableView, cellForRowAtIndexPath:indexPath) cell_id = "cell" cell = tableView.dequeueReusableCellWithIdentifier cell_id if cell.nil? cell = UITableViewCell.alloc.initWithStyle UITableViewCellStyleDefault, reuseIdentifier:cell_id end episode = @episodes[indexPath.row] cell.textLabel.text = episode.title cell end</strong> end That's it! Just run rake to see the application fetch content from an API and use it in a table view.