Building iOS Apps With RubyMotion

2769d4f1f9abeb4dd2438ff636a9e4dc?s=47 Ray Hightower
October 06, 2012

Building iOS Apps With RubyMotion

RubyMotion lets developers write native iOS apps using the Ruby programming language. Ray Hightower delivered this presentation at MagicRuby and Aloha Ruby in October 2012. Video is available at RayHightower.com.

2769d4f1f9abeb4dd2438ff636a9e4dc?s=128

Ray Hightower

October 06, 2012
Tweet

Transcript

  1. Building iOS Apps With RubyMotion Aloha Ruby October 8-9, 2012

    Honolulu, HI, USA
  2. @RayHightower WisdomGroup.com

  3. What Why How Q & A

  4. What

  5. Xcode + + Editor

  6. Why

  7. If you need a mobile MVP right now.

  8. If you want to learn more about Ruby.

  9. Why not?

  10. Ruby’s future on iOS?

  11. How

  12. ~/Code/Ruby/RubyMotion/helloruby$ rake Build ./build/iPhoneSimulator-6.0-Development Compile ./app/app_delegate.rb Compile ./app/home_controller.rb Link ./build/iPhoneSimulator-6.0-Development/helloruby.app/helloruby

    Create ./build/iPhoneSimulator-6.0-Development/helloruby.dSYM Simulate ./build/iPhoneSimulator-6.0-Development/helloruby.app (main)>
  13. ~/Code/Ruby/RubyMotion$ motion create helloruby Create helloruby Create helloruby/.gitignore Create helloruby/Rakefile

    Create helloruby/app Create helloruby/app/app_delegate.rb Create helloruby/resources Create helloruby/spec Create helloruby/spec/main_spec.rb ~/Code/Ruby/RubyMotion$
  14. ~/Code/Ruby/RubyMotion$ cd helloruby/ ~/Code/Ruby/RubyMotion/helloruby$ tree . !"" Rakefile !"" app

    # $"" app_delegate.rb !"" resources $"" spec $"" main_spec.rb 3 directories, 3 files ~/Code/Ruby/RubyMotion/helloruby$
  15. ~/Code/Ruby/RubyMotion$ cd helloruby/ ~/Code/Ruby/RubyMotion/helloruby$ tree . !"" Rakefile !"" app

    # $"" app_delegate.rb !"" resources $"" spec $"" main_spec.rb 3 directories, 3 files ~/Code/Ruby/RubyMotion/helloruby$
  16. ~/Code/Ruby/RubyMotion$ cd helloruby/ ~/Code/Ruby/RubyMotion/helloruby$ tree . !"" Rakefile !"" app

    # $"" app_delegate.rb !"" resources $"" spec $"" main_spec.rb 3 directories, 3 files ~/Code/Ruby/RubyMotion/helloruby$
  17. ~/Code/Ruby/RubyMotion$ cd helloruby/ ~/Code/Ruby/RubyMotion/helloruby$ tree . !"" Rakefile !"" app

    # $"" app_delegate.rb !"" resources $"" spec $"" main_spec.rb 3 directories, 3 files ~/Code/Ruby/RubyMotion/helloruby$
  18. ~/Code/Ruby/RubyMotion$ cd helloruby/ ~/Code/Ruby/RubyMotion/helloruby$ tree . !"" Rakefile !"" app

    # $"" app_delegate.rb !"" resources $"" spec $"" main_spec.rb 3 directories, 3 files ~/Code/Ruby/RubyMotion/helloruby$
  19. 1 class AppDelegate 2 def application(application, didFinishLaunchingWithOptions:launchOptions) 3 @window =

    UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds) 4 @window.rootViewController = HomeController.new 5 @window.makeKeyAndVisible 6 7 @window.backgroundColor = UIColor.grayColor 8 9 true 10 end 11 end 1 class AppDelegate
  20. 1 class AppDelegate 2 def application(application, didFinishLaunchingWithOptions:launchOptions) 3 @window =

    UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds) 4 @window.rootViewController = HomeController.new 5 @window.makeKeyAndVisible 6 7 @window.backgroundColor = UIColor.grayColor 8 9 true 10 end 11 end 2 def application(application, didFinishLaunchingWithOptions:launchOptions)
  21. 1 class AppDelegate 2 def application(application, didFinishLaunchingWithOptions:launchOptions) 3 @window =

    UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds) 4 @window.rootViewController = HomeController.new 5 @window.makeKeyAndVisible 6 7 @window.backgroundColor = UIColor.grayColor 8 9 true 10 end 11 end 3 @window = UIWindow.alloc.initWithFrame (UIScreen.mainScreen.bounds)
  22. 1 class AppDelegate 2 def application(application, didFinishLaunchingWithOptions:launchOptions) 3 @window =

    UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds) 4 @window.rootViewController = HomeController.new 5 @window.makeKeyAndVisible 6 7 @window.backgroundColor = UIColor.grayColor 8 9 true 10 end 11 end 4 @window.rootViewController = HomeController.new
  23. 1 class AppDelegate 2 def application(application, didFinishLaunchingWithOptions:launchOptions) 3 @window =

    UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds) 4 @window.rootViewController = HomeController.new 5 @window.makeKeyAndVisible 6 7 @window.backgroundColor = UIColor.grayColor 8 9 true 10 end 11 end 5 @window.makeKeyAndVisible
  24. 1 class AppDelegate 2 def application(application, didFinishLaunchingWithOptions:launchOptions) 3 @window =

    UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds) 4 @window.rootViewController = HomeController.new 5 @window.makeKeyAndVisible 6 7 @window.backgroundColor = UIColor.grayColor 8 9 true 10 end 11 end 7 @window.backgroundColor = UIColor.grayColor
  25. ~/Code/Ruby/RubyMotion/helloruby$ tree . !"" Rakefile !"" app # !"" app_delegate.rb

    # $"" home_controller.rb !"" resources $"" spec $"" main_spec.rb 3 directories, 4 files ~/Code/Ruby/RubyMotion/helloruby$
  26. 1 class HomeController < UIViewController 2 def loadView 3 self.view

    = UIView.alloc.init 4 end 5 6 def viewDidLoad 7 label = UILabel.alloc.initWithFrame([[15,100], [280,140]]) 8 label.text = "Hello MagicRuby!" 9 label.font = UIFont.boldSystemFontOfSize(25) 10 label.textColor = UIColor.blueColor 11 label.textAlignment = UITextAlignmentCenter 12 view.addSubview(label) 13 end 14 15 end 1 class HomeController < UIViewController
  27. 1 class HomeController < UIViewController 2 def loadView 3 self.view

    = UIView.alloc.init 4 end 5 6 def viewDidLoad 7 label = UILabel.alloc.initWithFrame([[15,100], [280,140]]) 8 label.text = "Hello Ruby!" 9 label.font = UIFont.boldSystemFontOfSize(25) 10 label.textColor = UIColor.blueColor 11 label.textAlignment = UITextAlignmentCenter 12 view.addSubview(label) 13 end 14 15 end 2 def loadView
  28. 1 class HomeController < UIViewController 2 def loadView 3 self.view

    = UIView.alloc.init 4 end 5 6 def viewDidLoad 7 label = UILabel.alloc.initWithFrame([[15,100], [280,140]]) 8 label.text = "Hello Ruby!" 9 label.font = UIFont.boldSystemFontOfSize(25) 10 label.textColor = UIColor.blueColor 11 label.textAlignment = UITextAlignmentCenter 12 view.addSubview(label) 13 end 14 15 end 6 def viewDidLoad
  29. 1 class HomeController < UIViewController 2 def loadView 3 self.view

    = UIView.alloc.init 4 end 5 6 def viewDidLoad 7 label = UILabel.alloc.initWithFrame([[15,100], [280,140]]) 8 label.text = "Hello Ruby!" 9 label.font = UIFont.boldSystemFontOfSize(25) 10 label.textColor = UIColor.blueColor 11 label.textAlignment = UITextAlignmentCenter 12 view.addSubview(label) 13 end 14 15 end 7 label = UILabel.alloc.initWithFrame( [[15,100],[280,140]])
  30. What about UX?

  31. Human Interface Guidelines (HIG)

  32. http://developer.apple.com/library/IOs/#documentation/UIKit/Reference/UIKit_Framework/Introduction/Introduction.html UIKit

  33. http://developer.apple.com/library/IOs/#documentation/UIKit/Reference/UIKit_Framework/Introduction/Introduction.html UIKit

  34. NSObject UIViewController UIWindow UIKit UIView UILabel UITableView

  35. 3: Fizz 5: Buzz 15: FizzBuzz

  36. Interface Builder .xib files

  37. view.viewWithTag 1

  38. view.viewWithTag 2

  39. view.viewWithTag 3

  40. view.viewWithTag 4

  41. ~/Code/Ruby/RubyMotion$ cd helloruby/ ~/Code/Ruby/RubyMotion/helloruby$ tree . !"" Rakefile !"" app

    # $"" app_delegate.rb !"" resources $"" spec $"" main_spec.rb 3 directories, 3 files ~/Code/Ruby/RubyMotion/helloruby$
  42. resources/fbib.xib

  43. 1 class FizzBuzzViewController < UIViewController 2 3 def loadView 4

    views = NSBundle.mainBundle.loadNibNamed "fbib", owner:self, options:nil 5 self.view = views[0] 6 @counter = 0 7 @view_handle = self.view 8 end 4 views = NSBundle.mainBundle.loadNibNamed"fbib", owner:self, options:nil
  44. 10 def viewDidLoad 11 @label = view.viewWithTag 1 12 plus_button

    = view.viewWithTag 2 13 minus_button = view.viewWithTag 3 14 reset_button = view.viewWithTag 4 15 end
  45. TDD MacBacon, Guard, & rm-redgreen

  46. ~/Code/Ruby/RubyMotion/fizzbuzzrm[master]$ tree . !"" Gemfile !"" Gemfile.lock !"" Guardfile !""

    Rakefile !"" app # !"" app.rb # !"" app_delegate.rb # !"" fizzbuzz_view_controller.rb # !"" home_controller.rb # !"" kernel.rb # !"" rm-ansiterm.rb # $"" string.rb !"" interfaces !"" resources # !"" f.png # !"" fbib.xib # !"" fizzbuzzbackground.jpg # $"" fizzbuzzbackground.png $"" spec !"" 00-redgreen.rb !"" home_controller_spec.rb $"" main_spec.rb 4 directories, 18 files ~/Code/Ruby/RubyMotion/fizzbuzzrm[master]$ $" spec !" 00-redgreen.rb !" home_controller_spec.rb $" main_spec.rb
  47. 1 describe "FizzBuzz Calculator Function" do 2 before do 3

    @this_number = 38 4 end 5 ... 17 18 (1..10).each do |this_number| 19 if this_number % 15 == 0 20 it 'should return buzz for multiples of 15' do 21 HomeController.fizzbuzz_calc(this_number).should == 'fizzbuzz' 22 end 23 elsif this_number % 3 == 0 24 it 'should return fizz for multiples of 3' do 25 HomeController.fizzbuzz_calc(this_number).should == 'fizz' 26 end 27 elsif this_number % 5 == 0 28 it 'should return buzz for multiples of 5' do 29 HomeController.fizzbuzz_calc(this_number).should == 'buzz' 30 end 31 else 32 it 'should return the original number' do 33 HomeController.fizzbuzz_calc(this_number).should == this_number 34 end 35 end 36 end 37 end home_controller_spec.rb
  48. describe "FizzBuzz Calculator Function" do before do @this_number = 38

    end ... (1..10).each do |this_number| if this_number % 15 == 0 it 'should return buzz for mults of 15' do HomeController.fizzbuzz_calc(this_number) .should == 'fizzbuzz' end home_controller_spec.rb
  49. $ gem install formotion

  50. 1 $:.unshift("/Library/RubyMotion/lib") 2 require 'motion/project' 3 require "bundler/gem_tasks" 4 require

    "bundler/setup" 5 6 $:.unshift("./lib/") 7 require './lib/formotion' 8 9 Motion::Project::App.setup do |app| 10 # Use `rake config' for project settings. 11 app.name = 'Formotion' 12 end Rakefile Source: http://clayallsopp.com
  51. 1 class LoginController < Formotion::FormController 2 def init 3 form

    = Formotion::Form.new({ 4 title: "Login", 5 sections: [{ 6 rows: [{ 7 title: "User Name", 8 type: :string, 9 placeholder: "name", 10 key: :user 11 }, { 12 ... login_controller.rb Source: http://clayallsopp.com
  52. Source: http://clayallsopp.com

  53. Source: http://clayallsopp.com

  54. $ gem install bubble-wrap

  55. // Objective-C [button addTarget:self action:@selector(buttonTapped:) forControlEvents: UIControlEventTouchUpInside]; - (void)buttonTapped:(id)sender {

    self.view.backgroundColor = [UIColor redColor]; } # RubyMotion with BubbleWrap button.when(UIControlEventTouchUpInside) do self.view.backgroundColor = UIColor.redColor end Source: http://clayallsopp.com/posts/the-ruby-motion-way/
  56. 2 $:.unshift("/Library/RubyMotion/lib") 3 require 'motion/project' 4 require 'bubble-wrap/core' 5 require

    'bubble-wrap/http' 6 7 Motion::Project::App.setup do |app| 8 # Use `rake config'... 9 app.name = 'NSScreencast' 10 end Rakefile Source: Ben Scheirman of http://nsscreencast.com/
  57. 1 class ApiClient 2 def self.fetch_episodes(&block) 3 @myurl = "http://nsscreencast.com/api/episodes.json"

    4 BubbleWrap::HTTP.get(@myurl) do |response| 5 if response.ok? 6 json = BubbleWrap::JSON.parse(response.body) 7 episodes = json.map {|ej| Episode.from_json(ej["episode"])} 8 block.call(true, episodes) 9 else 10 block.call(false, nil) 11 end 12 end 13 end 14 end api_client.rb Source: Ben Scheirman of http://nsscreencast.com/
  58. Source: Ben Scheirman of http://nsscreencast.com/

  59. Ruby Tools with RubyMotion

  60. Ruby Version Manager (RVM)

  61. $ gem install cupertino

  62. ~/Code/Ruby/RubyMotion$ ios profiles:list +----------------------------------+--------------+---------+ | Profile | App ID |

    Status | +----------------------------------+--------------+---------+ | WisdomGroup iOS Development | ABCDEFGHIJ.* | Active | | WisdomGroup RubyMotion | ABCDEFGHIJ.* | Active | | ChicagoRubyRubyMotion iPad | ABCDEFGHIJ.* | Active | | iOS Team Provisioning Profile: * | ABCDEFGHIJ.* | Active | | RTHiPhone4S | ABCDEFGHIJ.* | Active | +----------------------------------+--------------+---------+ ~/Code/Ruby/RubyMotion$ ios help
  63. Auto Layout ARC

  64. RubyMotion or Objective-C ?

  65. Resources http://rubymotion-tutorial.com Multi-page tutorial by Clay Allsopp. Also see http://clayallsopp.com

    http://pragmaticstudio.com/screencasts/rubymotion Pragmatic Studio’s intro to RubyMotion (free) plus a paid intro to Ruby. http://chicagoruby.org/videos/archives/2012/09/04/rubymotion-for-rubyists/ Bill Svec builds a simple RubyMotion weather app in about 90 minutes. http://motioncasts.tv Tutorial videos by Michael Erasmus and Hendrik Swanepoel. http://nshipster.com Mattt Thompson's weekly journal of Objective-C and Cocoa. http://nsscreencast.com/ Ben Scheirman’s Objective-C screencasts, plus a short one on RubyMotion. http://4steps5minutes.com Minimum viable products (MVPs) described in a 5-minute video.
  66. @RayHightower Thanks!