SlideShare une entreprise Scribd logo
1  sur  76
RubyMotion
iOS Development with Ruby
      @markbates
I HATE iOS
DEVELOPMENT!
Why I Hate iOS Development
Why I Hate iOS Development

✦   XCode
Why I Hate iOS Development

✦   XCode
✦   Objective-C
Why I Hate iOS Development

✦   XCode
✦   Objective-C
✦   Cocoa/iOS APIs
XCode
Objective-C
# 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"
// 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"];
now = -> {
  puts "The date and time is: #{Time.now}"
}

now.call
void (^now)(void) = ^ {
  NSDate *date = [NSDate date];
  NSLog(@"The date and time is %@", date);
};

now();
Cocoa/iOS APIs
require 'net/http'
require 'json'

url = "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.inspect
else
  puts "An Error Occurred (#{response.code}): #{response.body}"
end
- (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;
  }
}
Laurent Sansonetti

✦   Worked for Apple for 7 years on iLife and
    OS X

✦   Developed MacRuby

✦   Developed RubyCocoa

✦   Belgian
So What Does it Do?
So What Does it Do?
✦   Ruby!!! (NO OBJECTIVE-C!)
So What Does it Do?
✦   Ruby!!! (NO OBJECTIVE-C!)

✦   Keep Your Editor (NO XCODE!)
So What Does it Do?
✦   Ruby!!! (NO OBJECTIVE-C!)

✦   Keep Your Editor (NO XCODE!)

✦   IRB
So What Does it Do?
✦   Ruby!!! (NO OBJECTIVE-C!)

✦   Keep Your Editor (NO XCODE!)

✦   IRB

✦   Terminal Based Workflow (Rake)
So What Does it Do?
✦   Ruby!!! (NO OBJECTIVE-C!)

✦   Keep Your Editor (NO XCODE!)

✦   IRB

✦   Terminal Based Workflow (Rake)

✦   Testing Framework (MacBacon)
So What Does it Do?
✦   Ruby!!! (NO OBJECTIVE-C!)       ✦   Native Applications

✦   Keep Your Editor (NO XCODE!)

✦   IRB

✦   Terminal Based Workflow (Rake)

✦   Testing Framework (MacBacon)
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)
Suck it Objective-C!
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);
   }
   
 }];
url = NSURL.URLWithString("http://www.apple.com")
request = NSURLRequest.requestWithURL(url)
queue = NSOperationQueue.alloc.init

NSURLConnection.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)
But What About Those Weird
Named Argument Methods?
- (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
}
def tableView(tableView, didSelectRowAtIndexPath: indexPath)
  # do something
end

def tableView(tableView, numberOfRowsInSection: section)
  # do something
end

def tableView(tableView, cellForRowAtIndexPath: indexPath)
  # do something
end
Demo Time
Bubble Wrap
https://github.com/rubymotion/BubbleWrap
HTTP
data = {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)
 end
end
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 "It's #{Time.now}" }
# Runs the block after 0.5 seconds.
> App.open_url("http://matt.aimonetti.net")
# Opens the url using the device's 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']
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
Camera
# Uses the front camera
BW::Device.camera.front.picture(media_types: [:movie, :image]) do |result|
 image_view = UIImageView.alloc.initWithImage(result[:original_image])
end

# Uses the rear camera
BW::Device.camera.rear.picture(media_types: [:movie, :image]) do |result|
 image_view = UIImageView.alloc.initWithImage(result[:original_image])
end

# Uses the photo library
BW::Device.camera.any.picture(media_types: [:movie, :image]) do |result|
 image_view = UIImageView.alloc.initWithImage(result[:original_image])
end
JSON

BW::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"}
Media

# Plays in your custom frame
local_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.view
end

# Plays in an independent modal controller
BW::Media.play_modal("http://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3")
Deferrables
> d = EM::DefaultDeferrable.new
=> #<BubbleWrap::Reactor::DefaultDeferrable:0x6d859a0>
> d.callback { |what| puts "Great #{what}!" }
=> [#<Proc:0x6d8a1e0>]
> d.succeed "justice"
Great justice!
=> nil
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]
More...
✦   Localization                            ✦   Location

✦   Color                                   ✦   Gestures

✦   UUID Generator                          ✦   RSS Parser

✦   NSNotificationCenter                     ✦   Reactor

✦   Persistence                             ✦   Timers

✦   Observers

✦   String (underscore, camelize, etc...)
Pros & Cons
The Pros
The Pros
✦   Ruby!!
The Pros
✦   Ruby!!

✦   IDE Agnostic
The Pros
✦   Ruby!!

✦   IDE Agnostic

✦   “Wrapper” Gems
The Pros
✦   Ruby!!

✦   IDE Agnostic

✦   “Wrapper” Gems

✦   Fast
The Pros
✦   Ruby!!

✦   IDE Agnostic

✦   “Wrapper” Gems

✦   Fast

✦   IRB
The Pros
✦   Ruby!!               ✦   Easy to test

✦   IDE Agnostic

✦   “Wrapper” Gems

✦   Fast

✦   IRB
The Pros
✦   Ruby!!               ✦   Easy to test

✦   IDE Agnostic         ✦   Growing community

✦   “Wrapper” Gems

✦   Fast

✦   IRB
The Pros
✦   Ruby!!               ✦   Easy to test

✦   IDE Agnostic         ✦   Growing community

✦   “Wrapper” Gems       ✦   Frequent updates

✦   Fast

✦   IRB
The Cons
The Cons
✦   Cost - $199
The Cons
✦   Cost - $199

✦   Existing tutorials in Objective-C
The Cons
✦   Cost - $199

✦   Existing tutorials in Objective-C

✦   Maintainability?
The Cons
✦   Cost - $199

✦   Existing tutorials in Objective-C

✦   Maintainability?

✦   No Debugger (Yet)
The Cons
✦   Cost - $199

✦   Existing tutorials in Objective-C

✦   Maintainability?

✦   No Debugger (Yet)

✦   Difficult to work with Interface Builder
The Verdict
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

Contenu connexe

Tendances

The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5arajivmordani
 
Rails for Beginners - Le Wagon
Rails for Beginners - Le WagonRails for Beginners - Le Wagon
Rails for Beginners - Le WagonAlex Benoit
 
How to build an AngularJS backend-ready app WITHOUT BACKEND
How to build an AngularJS backend-ready app WITHOUT BACKEND How to build an AngularJS backend-ready app WITHOUT BACKEND
How to build an AngularJS backend-ready app WITHOUT BACKEND Enrique Oriol Bermúdez
 
James Thomas - Serverless Machine Learning With TensorFlow - Codemotion Berli...
James Thomas - Serverless Machine Learning With TensorFlow - Codemotion Berli...James Thomas - Serverless Machine Learning With TensorFlow - Codemotion Berli...
James Thomas - Serverless Machine Learning With TensorFlow - Codemotion Berli...Codemotion
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsMike Subelsky
 
"Writing Maintainable JavaScript". Jon Bretman, Badoo
"Writing Maintainable JavaScript". Jon Bretman, Badoo"Writing Maintainable JavaScript". Jon Bretman, Badoo
"Writing Maintainable JavaScript". Jon Bretman, BadooYandex
 
Intro to Ember.js
Intro to Ember.jsIntro to Ember.js
Intro to Ember.jsJay Phelps
 
Javascript - The Good, the Bad and the Ugly
Javascript - The Good, the Bad and the UglyJavascript - The Good, the Bad and the Ugly
Javascript - The Good, the Bad and the UglyThorsten Suckow-Homberg
 
Workshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte IWorkshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte IVisual Engineering
 
Vue.js + Django - configuración para desarrollo con webpack y HMR
Vue.js + Django - configuración para desarrollo con webpack y HMRVue.js + Django - configuración para desarrollo con webpack y HMR
Vue.js + Django - configuración para desarrollo con webpack y HMRJavier Abadía
 
Bee Smalltalk RunTime: anchor's aweigh
Bee Smalltalk RunTime: anchor's aweighBee Smalltalk RunTime: anchor's aweigh
Bee Smalltalk RunTime: anchor's aweighESUG
 
Refresh Austin - Intro to Dexy
Refresh Austin - Intro to DexyRefresh Austin - Intro to Dexy
Refresh Austin - Intro to Dexyananelson
 
Crafting Quality PHP Applications (Bucharest Tech Week 2017)
Crafting Quality PHP Applications (Bucharest Tech Week 2017)Crafting Quality PHP Applications (Bucharest Tech Week 2017)
Crafting Quality PHP Applications (Bucharest Tech Week 2017)James Titcumb
 
Crafting Quality PHP Applications (PHP Benelux 2018)
Crafting Quality PHP Applications (PHP Benelux 2018)Crafting Quality PHP Applications (PHP Benelux 2018)
Crafting Quality PHP Applications (PHP Benelux 2018)James Titcumb
 

Tendances (20)

Boost your angular app with web workers
Boost your angular app with web workersBoost your angular app with web workers
Boost your angular app with web workers
 
The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5a
 
Rails for Beginners - Le Wagon
Rails for Beginners - Le WagonRails for Beginners - Le Wagon
Rails for Beginners - Le Wagon
 
How to build an AngularJS backend-ready app WITHOUT BACKEND
How to build an AngularJS backend-ready app WITHOUT BACKEND How to build an AngularJS backend-ready app WITHOUT BACKEND
How to build an AngularJS backend-ready app WITHOUT BACKEND
 
James Thomas - Serverless Machine Learning With TensorFlow - Codemotion Berli...
James Thomas - Serverless Machine Learning With TensorFlow - Codemotion Berli...James Thomas - Serverless Machine Learning With TensorFlow - Codemotion Berli...
James Thomas - Serverless Machine Learning With TensorFlow - Codemotion Berli...
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web Apps
 
"Writing Maintainable JavaScript". Jon Bretman, Badoo
"Writing Maintainable JavaScript". Jon Bretman, Badoo"Writing Maintainable JavaScript". Jon Bretman, Badoo
"Writing Maintainable JavaScript". Jon Bretman, Badoo
 
jQuery in 15 minutes
jQuery in 15 minutesjQuery in 15 minutes
jQuery in 15 minutes
 
Intro to Ember.JS 2016
Intro to Ember.JS 2016Intro to Ember.JS 2016
Intro to Ember.JS 2016
 
Intro to Ember.js
Intro to Ember.jsIntro to Ember.js
Intro to Ember.js
 
What's new in iOS9
What's new in iOS9What's new in iOS9
What's new in iOS9
 
jQuery: Events, Animation, Ajax
jQuery: Events, Animation, AjaxjQuery: Events, Animation, Ajax
jQuery: Events, Animation, Ajax
 
Javascript - The Good, the Bad and the Ugly
Javascript - The Good, the Bad and the UglyJavascript - The Good, the Bad and the Ugly
Javascript - The Good, the Bad and the Ugly
 
Workshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte IWorkshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte I
 
Vue.js + Django - configuración para desarrollo con webpack y HMR
Vue.js + Django - configuración para desarrollo con webpack y HMRVue.js + Django - configuración para desarrollo con webpack y HMR
Vue.js + Django - configuración para desarrollo con webpack y HMR
 
Bee Smalltalk RunTime: anchor's aweigh
Bee Smalltalk RunTime: anchor's aweighBee Smalltalk RunTime: anchor's aweigh
Bee Smalltalk RunTime: anchor's aweigh
 
Refresh Austin - Intro to Dexy
Refresh Austin - Intro to DexyRefresh Austin - Intro to Dexy
Refresh Austin - Intro to Dexy
 
Crafting Quality PHP Applications (Bucharest Tech Week 2017)
Crafting Quality PHP Applications (Bucharest Tech Week 2017)Crafting Quality PHP Applications (Bucharest Tech Week 2017)
Crafting Quality PHP Applications (Bucharest Tech Week 2017)
 
YQL & Yahoo! Apis
YQL & Yahoo! ApisYQL & Yahoo! Apis
YQL & Yahoo! Apis
 
Crafting Quality PHP Applications (PHP Benelux 2018)
Crafting Quality PHP Applications (PHP Benelux 2018)Crafting Quality PHP Applications (PHP Benelux 2018)
Crafting Quality PHP Applications (PHP Benelux 2018)
 

Similaire à RubyMotion

Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasminePaulo Ragonha
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryTatsuhiko Miyagawa
 
Mac ruby to the max - Brendan G. Lim
Mac ruby to the max - Brendan G. LimMac ruby to the max - Brendan G. Lim
Mac ruby to the max - Brendan G. LimThoughtWorks
 
MacRuby to The Max
MacRuby to The MaxMacRuby to The Max
MacRuby to The MaxBrendan Lim
 
Quick and Easy Development with Node.js and Couchbase Server
Quick and Easy Development with Node.js and Couchbase ServerQuick and Easy Development with Node.js and Couchbase Server
Quick and Easy Development with Node.js and Couchbase ServerNic Raboy
 
Javascript Everywhere
Javascript EverywhereJavascript Everywhere
Javascript EverywherePascal Rettig
 
Ruby MVC from scratch with Rack
Ruby MVC from scratch with RackRuby MVC from scratch with Rack
Ruby MVC from scratch with RackDonSchado
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 
Future of Web Apps: Google Gears
Future of Web Apps: Google GearsFuture of Web Apps: Google Gears
Future of Web Apps: Google Gearsdion
 
Event-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineEvent-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineRicardo Silva
 
PySpark with Juypter
PySpark with JuypterPySpark with Juypter
PySpark with JuypterLi Ming Tsai
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011Nick Sieger
 
Developing cross platform desktop application with Ruby
Developing cross platform desktop application with RubyDeveloping cross platform desktop application with Ruby
Developing cross platform desktop application with RubyAnis Ahmad
 
MOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentMOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentanistar sung
 
Meetup uikit programming
Meetup uikit programmingMeetup uikit programming
Meetup uikit programmingjoaopmaia
 
Front End Development: The Important Parts
Front End Development: The Important PartsFront End Development: The Important Parts
Front End Development: The Important PartsSergey Bolshchikov
 

Similaire à RubyMotion (20)

Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
mobl
moblmobl
mobl
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
 
Mac ruby to the max - Brendan G. Lim
Mac ruby to the max - Brendan G. LimMac ruby to the max - Brendan G. Lim
Mac ruby to the max - Brendan G. Lim
 
MacRuby to The Max
MacRuby to The MaxMacRuby to The Max
MacRuby to The Max
 
Quick and Easy Development with Node.js and Couchbase Server
Quick and Easy Development with Node.js and Couchbase ServerQuick and Easy Development with Node.js and Couchbase Server
Quick and Easy Development with Node.js and Couchbase Server
 
JavaScript ES6
JavaScript ES6JavaScript ES6
JavaScript ES6
 
"Javascript" por Tiago Rodrigues
"Javascript" por Tiago Rodrigues"Javascript" por Tiago Rodrigues
"Javascript" por Tiago Rodrigues
 
Javascript Everywhere
Javascript EverywhereJavascript Everywhere
Javascript Everywhere
 
Ruby MVC from scratch with Rack
Ruby MVC from scratch with RackRuby MVC from scratch with Rack
Ruby MVC from scratch with Rack
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
Intro to appcelerator
Intro to appceleratorIntro to appcelerator
Intro to appcelerator
 
Future of Web Apps: Google Gears
Future of Web Apps: Google GearsFuture of Web Apps: Google Gears
Future of Web Apps: Google Gears
 
Event-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineEvent-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 Engine
 
PySpark with Juypter
PySpark with JuypterPySpark with Juypter
PySpark with Juypter
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
 
Developing cross platform desktop application with Ruby
Developing cross platform desktop application with RubyDeveloping cross platform desktop application with Ruby
Developing cross platform desktop application with Ruby
 
MOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentMOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app development
 
Meetup uikit programming
Meetup uikit programmingMeetup uikit programming
Meetup uikit programming
 
Front End Development: The Important Parts
Front End Development: The Important PartsFront End Development: The Important Parts
Front End Development: The Important Parts
 

Plus de Mark

Building Go Web Apps
Building Go Web AppsBuilding Go Web Apps
Building Go Web AppsMark
 
Angular.js Fundamentals
Angular.js FundamentalsAngular.js Fundamentals
Angular.js FundamentalsMark
 
Go(lang) for the Rubyist
Go(lang) for the RubyistGo(lang) for the Rubyist
Go(lang) for the RubyistMark
 
Mangling Ruby with TracePoint
Mangling Ruby with TracePointMangling Ruby with TracePoint
Mangling Ruby with TracePointMark
 
AngularJS vs. Ember.js vs. Backbone.js
AngularJS vs. Ember.js vs. Backbone.jsAngularJS vs. Ember.js vs. Backbone.js
AngularJS vs. Ember.js vs. Backbone.jsMark
 
A Big Look at MiniTest
A Big Look at MiniTestA Big Look at MiniTest
A Big Look at MiniTestMark
 
A Big Look at MiniTest
A Big Look at MiniTestA Big Look at MiniTest
A Big Look at MiniTestMark
 
GET /better
GET /betterGET /better
GET /betterMark
 
CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScriptMark
 
Testing Your JavaScript & CoffeeScript
Testing Your JavaScript & CoffeeScriptTesting Your JavaScript & CoffeeScript
Testing Your JavaScript & CoffeeScriptMark
 
Building an API in Rails without Realizing It
Building an API in Rails without Realizing ItBuilding an API in Rails without Realizing It
Building an API in Rails without Realizing ItMark
 
5 Favorite Gems (Lightning Talk(
5 Favorite Gems (Lightning Talk(5 Favorite Gems (Lightning Talk(
5 Favorite Gems (Lightning Talk(Mark
 
CoffeeScript for the Rubyist
CoffeeScript for the RubyistCoffeeScript for the Rubyist
CoffeeScript for the RubyistMark
 
Testing JavaScript/CoffeeScript with Mocha and Chai
Testing JavaScript/CoffeeScript with Mocha and ChaiTesting JavaScript/CoffeeScript with Mocha and Chai
Testing JavaScript/CoffeeScript with Mocha and ChaiMark
 
CoffeeScript for the Rubyist
CoffeeScript for the RubyistCoffeeScript for the Rubyist
CoffeeScript for the RubyistMark
 
Testing Rich Client Side Apps with Jasmine
Testing Rich Client Side Apps with JasmineTesting Rich Client Side Apps with Jasmine
Testing Rich Client Side Apps with JasmineMark
 
DRb and Rinda
DRb and RindaDRb and Rinda
DRb and RindaMark
 
CoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love AffairCoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love AffairMark
 
Distributed Programming with Ruby/Rubyconf 2010
Distributed Programming with Ruby/Rubyconf 2010Distributed Programming with Ruby/Rubyconf 2010
Distributed Programming with Ruby/Rubyconf 2010Mark
 

Plus de Mark (19)

Building Go Web Apps
Building Go Web AppsBuilding Go Web Apps
Building Go Web Apps
 
Angular.js Fundamentals
Angular.js FundamentalsAngular.js Fundamentals
Angular.js Fundamentals
 
Go(lang) for the Rubyist
Go(lang) for the RubyistGo(lang) for the Rubyist
Go(lang) for the Rubyist
 
Mangling Ruby with TracePoint
Mangling Ruby with TracePointMangling Ruby with TracePoint
Mangling Ruby with TracePoint
 
AngularJS vs. Ember.js vs. Backbone.js
AngularJS vs. Ember.js vs. Backbone.jsAngularJS vs. Ember.js vs. Backbone.js
AngularJS vs. Ember.js vs. Backbone.js
 
A Big Look at MiniTest
A Big Look at MiniTestA Big Look at MiniTest
A Big Look at MiniTest
 
A Big Look at MiniTest
A Big Look at MiniTestA Big Look at MiniTest
A Big Look at MiniTest
 
GET /better
GET /betterGET /better
GET /better
 
CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScript
 
Testing Your JavaScript & CoffeeScript
Testing Your JavaScript & CoffeeScriptTesting Your JavaScript & CoffeeScript
Testing Your JavaScript & CoffeeScript
 
Building an API in Rails without Realizing It
Building an API in Rails without Realizing ItBuilding an API in Rails without Realizing It
Building an API in Rails without Realizing It
 
5 Favorite Gems (Lightning Talk(
5 Favorite Gems (Lightning Talk(5 Favorite Gems (Lightning Talk(
5 Favorite Gems (Lightning Talk(
 
CoffeeScript for the Rubyist
CoffeeScript for the RubyistCoffeeScript for the Rubyist
CoffeeScript for the Rubyist
 
Testing JavaScript/CoffeeScript with Mocha and Chai
Testing JavaScript/CoffeeScript with Mocha and ChaiTesting JavaScript/CoffeeScript with Mocha and Chai
Testing JavaScript/CoffeeScript with Mocha and Chai
 
CoffeeScript for the Rubyist
CoffeeScript for the RubyistCoffeeScript for the Rubyist
CoffeeScript for the Rubyist
 
Testing Rich Client Side Apps with Jasmine
Testing Rich Client Side Apps with JasmineTesting Rich Client Side Apps with Jasmine
Testing Rich Client Side Apps with Jasmine
 
DRb and Rinda
DRb and RindaDRb and Rinda
DRb and Rinda
 
CoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love AffairCoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love Affair
 
Distributed Programming with Ruby/Rubyconf 2010
Distributed Programming with Ruby/Rubyconf 2010Distributed Programming with Ruby/Rubyconf 2010
Distributed Programming with Ruby/Rubyconf 2010
 

Dernier

Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 

Dernier (20)

Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 

RubyMotion

  • 2.
  • 3.
  • 5. Why I Hate iOS Development
  • 6. Why I Hate iOS Development ✦ XCode
  • 7. Why I Hate iOS Development ✦ XCode ✦ Objective-C
  • 8. Why I Hate iOS Development ✦ XCode ✦ Objective-C ✦ Cocoa/iOS APIs
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18. XCode
  • 19.
  • 20.
  • 21.
  • 22.
  • 24. # 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"
  • 25. // 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"];
  • 26. now = -> {   puts "The date and time is: #{Time.now}" } now.call
  • 27. void (^now)(void) = ^ {   NSDate *date = [NSDate date];   NSLog(@"The date and time is %@", date); }; now();
  • 29. require 'net/http' require 'json' url = "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.inspect else   puts "An Error Occurred (#{response.code}): #{response.body}" end
  • 30. - (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;   } }
  • 31.
  • 32.
  • 33. Laurent Sansonetti ✦ Worked for Apple for 7 years on iLife and OS X ✦ Developed MacRuby ✦ Developed RubyCocoa ✦ Belgian
  • 34. So What Does it Do?
  • 35. So What Does it Do? ✦ Ruby!!! (NO OBJECTIVE-C!)
  • 36. So What Does it Do? ✦ Ruby!!! (NO OBJECTIVE-C!) ✦ Keep Your Editor (NO XCODE!)
  • 37. So What Does it Do? ✦ Ruby!!! (NO OBJECTIVE-C!) ✦ Keep Your Editor (NO XCODE!) ✦ IRB
  • 38. So What Does it Do? ✦ Ruby!!! (NO OBJECTIVE-C!) ✦ Keep Your Editor (NO XCODE!) ✦ IRB ✦ Terminal Based Workflow (Rake)
  • 39. So What Does it Do? ✦ Ruby!!! (NO OBJECTIVE-C!) ✦ Keep Your Editor (NO XCODE!) ✦ IRB ✦ Terminal Based Workflow (Rake) ✦ Testing Framework (MacBacon)
  • 40. So What Does it Do? ✦ Ruby!!! (NO OBJECTIVE-C!) ✦ Native Applications ✦ Keep Your Editor (NO XCODE!) ✦ IRB ✦ Terminal Based Workflow (Rake) ✦ Testing Framework (MacBacon)
  • 41. 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)
  • 43. 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);    }      }];
  • 44. url = NSURL.URLWithString("http://www.apple.com") request = NSURLRequest.requestWithURL(url) queue = NSOperationQueue.alloc.init NSURLConnection.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)
  • 45. But What About Those Weird Named Argument Methods?
  • 46. - (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 }
  • 47. def tableView(tableView, didSelectRowAtIndexPath: indexPath)   # do something end def tableView(tableView, numberOfRowsInSection: section)   # do something end def tableView(tableView, cellForRowAtIndexPath: indexPath)   # do something end
  • 50. HTTP data = {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) end end
  • 51. 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 "It's #{Time.now}" } # Runs the block after 0.5 seconds. > App.open_url("http://matt.aimonetti.net") # Opens the url using the device's 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']
  • 52. 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
  • 53. Camera # Uses the front camera BW::Device.camera.front.picture(media_types: [:movie, :image]) do |result| image_view = UIImageView.alloc.initWithImage(result[:original_image]) end # Uses the rear camera BW::Device.camera.rear.picture(media_types: [:movie, :image]) do |result| image_view = UIImageView.alloc.initWithImage(result[:original_image]) end # Uses the photo library BW::Device.camera.any.picture(media_types: [:movie, :image]) do |result| image_view = UIImageView.alloc.initWithImage(result[:original_image]) end
  • 54. JSON BW::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"}
  • 55. Media # Plays in your custom frame local_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.view end # Plays in an independent modal controller BW::Media.play_modal("http://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3")
  • 56. Deferrables > d = EM::DefaultDeferrable.new => #<BubbleWrap::Reactor::DefaultDeferrable:0x6d859a0> > d.callback { |what| puts "Great #{what}!" } => [#<Proc:0x6d8a1e0>] > d.succeed "justice" Great justice! => nil
  • 57. 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]
  • 58. More... ✦ Localization ✦ Location ✦ Color ✦ Gestures ✦ UUID Generator ✦ RSS Parser ✦ NSNotificationCenter ✦ Reactor ✦ Persistence ✦ Timers ✦ Observers ✦ String (underscore, camelize, etc...)
  • 61. The Pros ✦ Ruby!!
  • 62. The Pros ✦ Ruby!! ✦ IDE Agnostic
  • 63. The Pros ✦ Ruby!! ✦ IDE Agnostic ✦ “Wrapper” Gems
  • 64. The Pros ✦ Ruby!! ✦ IDE Agnostic ✦ “Wrapper” Gems ✦ Fast
  • 65. The Pros ✦ Ruby!! ✦ IDE Agnostic ✦ “Wrapper” Gems ✦ Fast ✦ IRB
  • 66. The Pros ✦ Ruby!! ✦ Easy to test ✦ IDE Agnostic ✦ “Wrapper” Gems ✦ Fast ✦ IRB
  • 67. The Pros ✦ Ruby!! ✦ Easy to test ✦ IDE Agnostic ✦ Growing community ✦ “Wrapper” Gems ✦ Fast ✦ IRB
  • 68. The Pros ✦ Ruby!! ✦ Easy to test ✦ IDE Agnostic ✦ Growing community ✦ “Wrapper” Gems ✦ Frequent updates ✦ Fast ✦ IRB
  • 70. The Cons ✦ Cost - $199
  • 71. The Cons ✦ Cost - $199 ✦ Existing tutorials in Objective-C
  • 72. The Cons ✦ Cost - $199 ✦ Existing tutorials in Objective-C ✦ Maintainability?
  • 73. The Cons ✦ Cost - $199 ✦ Existing tutorials in Objective-C ✦ Maintainability? ✦ No Debugger (Yet)
  • 74. The Cons ✦ Cost - $199 ✦ Existing tutorials in Objective-C ✦ Maintainability? ✦ No Debugger (Yet) ✦ Difficult to work with Interface Builder
  • 76. 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

Notes de l'éditeur

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n