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
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
evc = EpisodesViewController.alloc.init
nav = UINavigationController.alloc.initWithRootViewController evc
@window.rootViewController = nav
@window.makeKeyAndVisible
true
end
end
Now, just type rake to run your application.
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'
require 'bubble-wrap/core'
require bubble-wrap/http'
...
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.
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
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 ||= []
ApiClient.fetch_episodes do |success, episodes|
if success
@episodes = episodes
p "Received #{@episodes.length} episodes"
self.tableView.reloadData
else
App.alert("Oops!")
end
end
end
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
end
That's it! Just run rake to see the application fetch content from an API and use it in a table view.