RubyMotion

4,587 views

Published on

Presented on 8/14/2012 at BostonRb. This talk provides a nice intro and overview of what RubyMotion is and whether or not it's worth incorporating into your development toolkit.

Published in: Technology
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,587
On SlideShare
0
From Embeds
0
Number of Embeds
45
Actions
Shares
0
Downloads
45
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • RubyMotion

    1. 1. RubyMotioniOS Development with Ruby @markbates
    2. 2. I HATE iOSDEVELOPMENT!
    3. 3. Why I Hate iOS Development
    4. 4. Why I Hate iOS Development✦ XCode
    5. 5. Why I Hate iOS Development✦ XCode✦ Objective-C
    6. 6. Why I Hate iOS Development✦ XCode✦ Objective-C✦ Cocoa/iOS APIs
    7. 7. XCode
    8. 8. Objective-C
    9. 9. # Create a new array (mutable):myArray = %w{hello world etc}myArray << "new value"# Create a new hash (mutable):myHash = {"key-a" => "value-a", "key-b" => "value-b"}myHash["key-c"] = "value-c"
    10. 10. // Create a new array:NSArray *myArray = [NSArray arrayWithObjects:@"hello",@"world",@"etc",nil];// Create a mutable array:NSMutableArray *myArray = [[NSMutableArray alloc] init];[myArray addObject:@"hello world"];// Create a dictionary (hash):NSDictionary *myDictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"value-a", @"key-a", @"value-b", @"key-b", nil];// Create a mutable dictionary:NSMutableDictionary *myDictionary = [NSMutableDictionary dictionary];[myDictionary setObject: @"value-c" forKey: @"key-c"];
    11. 11. now = -> {  puts "The date and time is: #{Time.now}"}now.call
    12. 12. void (^now)(void) = ^ {  NSDate *date = [NSDate date];  NSLog(@"The date and time is %@", date);};now();
    13. 13. Cocoa/iOS APIs
    14. 14. require net/httprequire jsonurl = "http://www.example.com/api.json"response = Net::HTTP.get_response(URI.parse(url))if response.code.to_i == 200  json = JSON.parse(response.body)  puts json.inspectelse  puts "An Error Occurred (#{response.code}): #{response.body}"end
    15. 15. - (void)viewDidLoad {  [super viewDidLoad];  responseData = [[NSMutableData data] retain];  NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.example.com/api.json"]];  [[NSURLConnection alloc] initWithRequest:request delegate:self];}- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {  [responseData setLength:0];}- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {  [responseData appendData:data];}- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {  label.text = [NSString stringWithFormat:@"Connection failed: %@", [error description]];}- (void)connectionDidFinishLoading:(NSURLConnection *)connection {  [connection release];  NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];  [responseData release];    NSError *error;  SBJSON *json = [[SBJSON new] autorelease];  NSArray *myArray = [json objectWithString:responseString error:&error];  [responseString release];    if (myArray == nil)    label.text = [NSString stringWithFormat:@"JSON parsing failed: %@", [error localizedDescription]];  else {    NSMutableString *text = [NSMutableString stringWithString:@"Array Data:n"];        for (int i = 0; i < [myArray count]; i++)      [text appendFormat:@"%@n", [myArray objectAtIndex:i]];    label.text = text;  }}
    16. 16. Laurent Sansonetti✦ Worked for Apple for 7 years on iLife and OS X✦ Developed MacRuby✦ Developed RubyCocoa✦ Belgian
    17. 17. So What Does it Do?
    18. 18. So What Does it Do?✦ Ruby!!! (NO OBJECTIVE-C!)
    19. 19. So What Does it Do?✦ Ruby!!! (NO OBJECTIVE-C!)✦ Keep Your Editor (NO XCODE!)
    20. 20. So What Does it Do?✦ Ruby!!! (NO OBJECTIVE-C!)✦ Keep Your Editor (NO XCODE!)✦ IRB
    21. 21. So What Does it Do?✦ Ruby!!! (NO OBJECTIVE-C!)✦ Keep Your Editor (NO XCODE!)✦ IRB✦ Terminal Based Workflow (Rake)
    22. 22. So What Does it Do?✦ Ruby!!! (NO OBJECTIVE-C!)✦ Keep Your Editor (NO XCODE!)✦ IRB✦ Terminal Based Workflow (Rake)✦ Testing Framework (MacBacon)
    23. 23. So What Does it Do?✦ Ruby!!! (NO OBJECTIVE-C!) ✦ Native Applications✦ Keep Your Editor (NO XCODE!)✦ IRB✦ Terminal Based Workflow (Rake)✦ Testing Framework (MacBacon)
    24. 24. So What Does it Do?✦ Ruby!!! (NO OBJECTIVE-C!) ✦ Native Applications✦ Keep Your Editor (NO XCODE!) ✦ App Store Approved✦ IRB✦ Terminal Based Workflow (Rake)✦ Testing Framework (MacBacon)
    25. 25. Suck it Objective-C!
    26. 26. NSString *urlAsString = @"http://www.apple.com";NSURL *url = [NSURL URLWithString:urlAsString];NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];NSOperationQueue *queue = [[NSOperationQueue alloc] init];[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response,                     NSData *data,                     NSError *error) {      if ([data length] >0 &&       error == nil){          /* Get the documents directory */     NSString *documentsDir =     [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,                                          NSUserDomainMask,                                          YES) objectAtIndex:0];          /* Append the file name to the documents directory */     NSString *filePath = [documentsDir                           stringByAppendingPathComponent:@"apple.html"];          /* Write the data to the file */     [data writeToFile:filePath            atomically:YES];          NSLog(@"Successfully saved the file to %@", filePath);        }   else if ([data length] == 0 &&            error == nil){     NSLog(@"Nothing was downloaded.");   }   else if (error != nil){     NSLog(@"Error happened = %@", error);   }    }];
    27. 27. url = NSURL.URLWithString("http://www.apple.com")request = NSURLRequest.requestWithURL(url)queue = NSOperationQueue.alloc.initNSURLConnection.sendAsynchronousRequest(request,  queue: queue,  completionHandler: lambda do |response, data, error|    if(data.length > 0 && error.nil?)      doc_dir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,                                                    NSUserDomainMask,                                                    true).first      #p doc_dir      file_path = doc_dir.stringByAppendingPathComponent("apple.html")      data.writeToFile(file_path, atomically: true)      p "Saved file to #{file_path}"    elsif( data.length == 0 && error.nil? )      p "Nothing was downloaded"    elsif(!error.nil?)      p "Error: #{error}"    end  end)
    28. 28. But What About Those WeirdNamed Argument Methods?
    29. 29. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {  // do something}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {  // do something}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {  // do something}
    30. 30. def tableView(tableView, didSelectRowAtIndexPath: indexPath)  # do somethingenddef tableView(tableView, numberOfRowsInSection: section)  # do somethingenddef tableView(tableView, cellForRowAtIndexPath: indexPath)  # do somethingend
    31. 31. Demo Time
    32. 32. Bubble Wraphttps://github.com/rubymotion/BubbleWrap
    33. 33. HTTPdata = {first_name: Matt, last_name: Aimonetti}BubbleWrap::HTTP.post("http://foo.bar.com/", {payload: data}) do |response| if response.ok? json = BubbleWrap::JSON.parse(response.body.to_str) p json[id] elsif response.status_code.to_s =~ /40d/ App.alert("Login failed") else App.alert(response.error_message) endend
    34. 34. App> App.documents_path# "~/iPhone Simulator/5.0/Applications/EEC6454E-1816-451E-BB9A-EE18222E1A8F/Documents"> App.resources_path# "~/iPhone Simulator/5.0/Applications/EEC64-1816-451E-BB9A-EE18221A8F/testSuite_spec.app"> App.name# "testSuite"> App.identifier# "io.bubblewrap.testSuite"> App.alert("BubbleWrap is awesome!")# creates and shows an alert message.> App.run_after(0.5) { p "Its #{Time.now}" }# Runs the block after 0.5 seconds.> App.open_url("http://matt.aimonetti.net")# Opens the url using the devices browser. (accepts a string url or an instance of NSURL.> App::Persistence[channels] # application specific persistence storage# [NBC, ABC, Fox, CBS, PBS]> App::Persistence[channels] = [TF1, France 2, France 3]# [TF1, France 2, France 3]
    35. 35. Device> Device.iphone?# true> Device.ipad?# false> Device.front_camera?# true> Device.rear_camera?# true> Device.orientation# :portrait> Device.simulator?# true> Device.retina?# false> Device.screen.width# 320> Device.screen.height# 480> Device.screen.width_for_orientation(:landscape_left)# 480> Device.screen.height_for_orientation(:landscape_left)# 320
    36. 36. Camera# Uses the front cameraBW::Device.camera.front.picture(media_types: [:movie, :image]) do |result| image_view = UIImageView.alloc.initWithImage(result[:original_image])end# Uses the rear cameraBW::Device.camera.rear.picture(media_types: [:movie, :image]) do |result| image_view = UIImageView.alloc.initWithImage(result[:original_image])end# Uses the photo libraryBW::Device.camera.any.picture(media_types: [:movie, :image]) do |result| image_view = UIImageView.alloc.initWithImage(result[:original_image])end
    37. 37. JSONBW::JSON.generate({foo => 1, bar => [1,2,3], baz => awesome})=> "{"foo":1,"bar":[1,2,3],"baz":"awesome"}"BW::JSON.parse "{"foo":1,"bar":[1,2,3],"baz":"awesome"}"=> {"foo"=>1, "bar"=>[1, 2, 3], "baz"=>"awesome"}
    38. 38. Media# Plays in your custom framelocal_file = NSURL.fileURLWithPath(File.join(NSBundle.mainBundle.resourcePath, test.mp3))BW::Media.play(local_file) do |media_player| media_player.view.frame = [[10, 100], [100, 100]] self.view.addSubview media_player.viewend# Plays in an independent modal controllerBW::Media.play_modal("http://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3")
    39. 39. Deferrables> d = EM::DefaultDeferrable.new=> #<BubbleWrap::Reactor::DefaultDeferrable:0x6d859a0>> d.callback { |what| puts "Great #{what}!" }=> [#<Proc:0x6d8a1e0>]> d.succeed "justice"Great justice!=> nil
    40. 40. Events> o = Class.new { include EM::Eventable }.new=> #<#<Class:0x6dc1310>:0x6dc2ec0>> o.on(:november_5_1955) { puts "Ow!" }=> [#<Proc:0x6dc6300>]> o.on(:november_5_1955) { puts "Flux capacitor!" }=> [#<Proc:0x6dc6300>, #<Proc:0x6dc1ba0>]> o.trigger(:november_5_1955)Ow!Flux capacitor!=> [nil, nil]
    41. 41. More...✦ Localization ✦ Location✦ Color ✦ Gestures✦ UUID Generator ✦ RSS Parser✦ NSNotificationCenter ✦ Reactor✦ Persistence ✦ Timers✦ Observers✦ String (underscore, camelize, etc...)
    42. 42. Pros & Cons
    43. 43. The Pros
    44. 44. The Pros✦ Ruby!!
    45. 45. The Pros✦ Ruby!!✦ IDE Agnostic
    46. 46. The Pros✦ Ruby!!✦ IDE Agnostic✦ “Wrapper” Gems
    47. 47. The Pros✦ Ruby!!✦ IDE Agnostic✦ “Wrapper” Gems✦ Fast
    48. 48. The Pros✦ Ruby!!✦ IDE Agnostic✦ “Wrapper” Gems✦ Fast✦ IRB
    49. 49. The Pros✦ Ruby!! ✦ Easy to test✦ IDE Agnostic✦ “Wrapper” Gems✦ Fast✦ IRB
    50. 50. The Pros✦ Ruby!! ✦ Easy to test✦ IDE Agnostic ✦ Growing community✦ “Wrapper” Gems✦ Fast✦ IRB
    51. 51. The Pros✦ Ruby!! ✦ Easy to test✦ IDE Agnostic ✦ Growing community✦ “Wrapper” Gems ✦ Frequent updates✦ Fast✦ IRB
    52. 52. The Cons
    53. 53. The Cons✦ Cost - $199
    54. 54. The Cons✦ Cost - $199✦ Existing tutorials in Objective-C
    55. 55. The Cons✦ Cost - $199✦ Existing tutorials in Objective-C✦ Maintainability?
    56. 56. The Cons✦ Cost - $199✦ Existing tutorials in Objective-C✦ Maintainability?✦ No Debugger (Yet)
    57. 57. The Cons✦ Cost - $199✦ Existing tutorials in Objective-C✦ Maintainability?✦ No Debugger (Yet)✦ Difficult to work with Interface Builder
    58. 58. The Verdict
    59. 59. Resources✦ http://www.rubymotion.com ✦ http://rubymotionapps.com/projects✦ http://rubymotion-tutorial.com ✦ http://pragmaticstudio.com/screencasts/ rubymotion✦ https://github.com/IconoclastLabs/ rubymotion_cookbook✦ https://github.com/railsfactory/ rubymotion-cookbook✦ https://twitter.com/RubyMotion✦ http://rubymotionweekly.com

    ×