SlideShare uma empresa Scribd logo
1 de 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

Mais conteúdo relacionado

Mais procurados

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
 

Mais procurados (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)
 

Semelhante a 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
 

Semelhante a 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
 

Mais 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
 

Mais 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
 

Último

Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontologyjohnbeverley2021
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistandanishmna97
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxRemote DBA Services
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 

Último (20)

Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 

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

Notas do Editor

  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