Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Objective-C vs. RubyMotion!

Objective-C vs. RubyMotion!

Presented at ChicagoRuby, Jan 8 2013.

David Demaree

January 08, 2013
Tweet

More Decks by David Demaree

Other Decks in Programming

Transcript

  1. Objective-C Invented in 1983, adopted by NeXT, currently maintained by

    Apple Pretty much used only for Apple platforms Statically typed object- oriented language Strict superset of C Preprocessed
  2. RubyMotion Implementation of Ruby 1.9 (sort of) on LLVM and

    the Objective-C runtime Closed-source compiler, available commercially for $199 (+ annual support fee) Open-source build tools, based on Rubygems and Rake
  3. iOS Developer Agreement 3.3.1 Applications may only use Documented APIs

    in the manner prescribed by Apple and must not use or call any private APIs. Applications must be originally written in Objective-C, C, C++, or JavaScript as executed by the iPhone OS WebKit engine, and only code written in C, C++, and Objective-C may compile and directly link against the Documented APIs (e.g., Applications that link to Documented APIs through an intermediary translation or compatibility layer or tool are prohibited).
  4. iOS Developer Agreement 3.3.1 Applications may only use Documented APIs

    in the manner prescribed by Apple and must not use or call any private APIs. Applications must be originally written in Objective-C, C, C++, or JavaScript as executed by the iPhone OS WebKit engine, and only code written in C, C++, and Objective-C may compile and directly link against the Documented APIs (e.g., Applications that link to Documented APIs through an intermediary translation or compatibility layer or tool are prohibited).
  5. Ruby source code ObjC libraries Cocoa frameworks Native iOS app

    RubyMotion calls Cocoa frameworks directly
  6. PhoneGap app (HTML/CSS/JS) Objective-C runtime Cocoa app (Objective-C) Cocoa app

    (RubyMotion) Compiles to Obj-C bytecode Compiles to Obj-C bytecode PhoneGap cross-platform runtime
  7. Classic Obj-C Modern Obj-C Brackets everywhere Properties & dot syntax

    Verbose code for working with basic object types Object literals Manual memory management ARC No blocks Blocks!
  8. @interface DDVenue : NSObject @property (strong) NSString *name; @property (strong)

    NSString *address; @property (strong) CLLocation *location; - (CLLocationDistance)distanceFromLocation:(CLLocation *)otherLocation; @end @implementation DDVenue @synthesize name, address, location; - (CLLocationDistance)distanceFromLocation:(CLLocation *)otherLocation { return [self.location distanceFromLocation:otherLocation]; } @end
  9. class Venue attr_accessor :name, :address, :location def distanceFromLocation(location) self.location.distanceFromLocation(location) end

    end Everything inherits from (NS)Object Dynamic/“duck” typing Implicit return All dot syntax, all the time
  10. class Venue attr_accessor :name, :address, :location def distanceFromLocation(location) self.location.distanceFromLocation(location) end

    end Everything inherits from (NS)Object Dynamic/“duck” typing Implicit return All dot syntax, all the time No interface file required
  11. @interface DDFood : NSObject { BOOL isPizza; } - (void)setIsPizza:(BOOL)value;

    @end @implementation DDFood - (void)setIsPizza:(BOOL)value { isPizza = value; } @end class Food def isPizza=(pizzaness) @isPizza = pizzaness end def isPizza! @isPizza = true end def isPizza? @isPizza ||= false end end Instance vars must be declared Anything with an @-sigil is an ivar
  12. // YellingString.rb class String def yell self + "!" end

    end "Kind of awesome".yell.yell.yell #=> "Kind of awesome!!!" // NSString+Yelling.h @interface NSString (Yelling) - (NSString*) yell; @end // NSString+Yelling.m @implementation NSString (Yelling) - (NSString*) yell { return [self stringByAppendingString:@"!"]; } @end [@"Kind of awesome" yell]; //=> @"Kind of awesome!" Classes extended via categories Classes can be reopened at any time
  13. Ruby has real namespaces NSString, GBFont, DDCoreDataManager MyApp::Venue, MyApp::Item, CoreData::Manager

    Objective-C class names are prefixed Ruby classes/modules can be nested inside each other
  14. Multiple inheritance via mixins module StaticTableViewController CellInfo = Struct.new(:text, :accessory_type,

    :action) def tableView(tableView, cellForRowAtIndexPath:indexPath) cell = self.infoForCells[indexPath.row] # Create and return a UITableViewCell end end module SettingsViewController < UITableViewController include StaticTableViewController end
  15. Blocks! class PlaceFinder def self.placeFinderWithBlock(&block) newFinder = self.alloc.init yield newFinder

    if block_given? return newFinder end end @finder = PlaceFinder.placeFinderWithBlock do |finder| finder.location = CLLocation.alloc.initWithLatitude(lat, longitude:lng) finder.numberOfResults = 10 end
  16. HTTP.get("http://github.com/ddemaree") do |response| p response.body.to_str # prints the response's body

    end @singleton = nil Dispatch.once do @singleton ||= self.alloc.initWithOptions({}) end Providing a completion callback for a HTTP request Initializing a singleton in a thread-safe way
  17. Enums and C structs typedef NS_ENUM(NSUInteger, GBListSettingsSection){ GBListSettingsBudgetToggleSection, GBListSettingsSectionLock, GBListSettingsSectionEmail,

    GBListSettingsSectionAll }; - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (section == GBListSettingsBudgetInclusionSection) { return 2; } } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return GBListSettingsSectionAll; }
  18. class PlacesViewController < UITableViewController SECTIONS = [:budget, :lock, :email] def

    tableView(tableView, numberOfRowsInSection:section) sectionName = SECTIONS[section] if sectionName == :budget return 2 end end def numberOfSectionsInTableView(tableView) SECTIONS.length end end
  19. RubyMotion’s C-like APIs Dispatch.once { @singleton ||= self.new } errorPtr

    = Pointer.new(:object) ABAddressBookCreateWithOptions(nil, errorPtr) Pointers are objects Functions are wrapped as methods on the Object class Grand Central Dispatch is wrapped as the Dispatch module
  20. Covering all of Cocoa with newer, simpler DSL abstractions is

    a stated goal of RubyMotion’s creators
  21. alert = UIAlertView.alloc.initWithTitle "Hey, buddy", message: "Buzz off!", delegate: nil,

    cancelButtonTitle: nil, otherButtonTitles: nil alert.show() App.alert("Hey, buddy", message: "Buzz off!") do |alert| # You can perform any additional configuration on the # UIAlertView object here, using the `alert` variable end BubbleWrap Standard Cocoa API (in RubyMotion)
  22. PhoneGap app (HTML/CSS/JS) Objective-C runtime Cocoa app (Objective-C) Cocoa app

    (RubyMotion) Compiles to Obj-C bytecode PhoneGap cross-platform runtime RubyMotion DSLs?
  23. VS Familiar (if you’re coming from Ruby/open-source development) Lighter-weight, which

    can be faster / more nimble Have it your way Supported by Apple Designed specifically for Cocoa/Cocoa Touch app development Excellent integrated documentation & code completion
  24. “Using XCode is like driving a very used, modern car

    - it routinely breaks down, freezes and screws up the rest of my system and there is no way to understand what it wrong because all the parts are hidden from you. For example, it will stop compiling and simply freeze, acting like it's doing something. It will kill other processes and cause them to freeze (terminal processes simply stop getting cycles). It will stop responding to step over, step in, etc actions. “If there is any way for you to avoid XCode, do so. So far, I have had to force quit 4 times since 9:00 AM.”
  25. Motion::Project::App.setup do |app| # Use `rake config' to see complete

    project settings. app.name = 'GiftBox' app.version = "2.0" app.interface_orientations = [:portrait] app.identifier = "me.demaree.GiftBox2" app.short_version = "190" app.frameworks += ["CoreData"] end RubyMotion configuration DSL