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

Wrapping iOS with RubyMotion

Wrapping iOS with RubyMotion

All about writing wrappers for RubyMotion

From RubyMotion #inspect 2013

F6c4ef1904591e41f767ba68268971cf?s=128

Clay Allsopp

March 29, 2013
Tweet

More Decks by Clay Allsopp

Other Decks in Programming

Transcript

  1. 8SBQQJOH J04XJUI 3VCZ.PUJPO By @clayallsopp

  2. 4PMJLF XIZ

  3. 4PMJLF XIZ

  4. 4PMJLF XIZ

  5. 8FMM XIZOPU

  6. 8IBUNBLFT B<8>SBQQFS

  7. 8SBQQFS

  8. 8SBQQFS

  9. #VUIPX

  10. %FMFHBUFT

  11. • UITableViewDelegate • tableView:heightForRowAtIndexPath: • UITableViewDataSource • UIImagePickerControllerDelegate • NSURLConnectionDelegate

    • CBCentralManagerDelegate • GKPeerPickerControllerDelegate • GOToHellDelegate
  12. None
  13. CLLocationManagerDelegate • locationManager:didUpdateToLocation :fromLocation:

  14. CLLocationManagerDelegate Location.get do |location| p location[:to] p location[:from] end

  15. module Location module_function def get(&callback) @callback = callback @location_manager =

    CLLocationManager.alloc.init @location_manager.delegate = self @location_manager.startUpdatingLocation end def locationManager(manager, didUpdateToLocation:new, fromLocation:old) @callback.call to: newLocation, from: oldLocation end end
  16. • What happens with concurrent @callback? • NSNotificationCenter • Multiple

    delegator objects (PUDIBT
  17. #MPDLT

  18. AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success: ^(NSURLRequest *request, NSHTTPURLResponse *response,

    id JSON) { NSLog(@"IP Address: %@", [JSON valueForKeyPath:@"origin"]); } failure: ^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON ) { NSLog(@"Error: %@", [error localizedDescription]); }]; AFNetworking
  19. operation = AFJSONRequestOperation.JSONRequestOperationWithRequest(request, success: lambda { |request, response, json| p

    "IP Address: #{json.valueForKeyPath('origin')}" }, failure: lambda { |request, response, error, json| { p "Error: #{error.localizedDescription}" })
  20. operation = AFJSONRequestOperation.JSONRequestOperationWithRequest(request, success: -> (request, response, json) { p

    "IP Address: #{json.valueForKeyPath('origin')}" }, failure: -> (request, response, error, json) { p "Error: #{error.localizedDescription}" })
  21. AFJSONRequestOperation.JSONRequestOperationWithRequest (request) do |one_thing| if one_thing.success? # hooray elsif one_thing.failure?

    # :( end end end
  22. module AFMotion module JSON def self.for_request(request, &callback) operation = AFJSONRequestOperation.JSONRequestOperationWithRequest(request,

    success: -> (request, response, json) { result = AFMotion::HTTPResult.new(operation, json, nil) callback.call(result) }, failure: -> (request, response, error, json) { result = AFMotion::HTTPResult.new(operation, json, error) callback.call(result) } ) end end end
  23. AFMotion::Operation::JSON.get("users") do |result| if result.success? p result.object elsif result.failure? p

    result.error.localizedDescription end end
  24. [AFJSONRequestOperation JSONRequestOperationWithRequest:request success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {

    NSLog(@"IP Address: %@", [JSON valueForKeyPath:@"origin"]); } failure: ^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON ) { NSLog(@"Error: %@", [error localizedDescription]); }];
  25. $POTUBOUT &OVNT

  26. picker = UIImagePickerController.alloc.init picker.sourceType = UIImagePickerControllerSourceTypeCamera view = UIView.alloc.initWithFrame(frame) view.autoresizingMask

    = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingPleaseNoMoreNotAgain
  27. class UIView def autoresizing_mask=(mask) self.autoresizingMask = Constants.get("UIViewAutoresizing", mask) end end

    picker.source_type = :camera view.autoresizing_mask = [:flexible_width, :flexible_height]
  28. module Constants module_function def get(base, value) case value when Integer

    value when NSArray value.reduce { |i, j| const_int_get(base, i) | const_int_get(base, j) } else value = value.to_s.camelize Kernel.const_get("#{base}#{value}") end end end github.com/clayallsopp/inspect-2013
  29. • Need to hard-code all possible constants as a method

    (PUDIBT class AppDelegate private def constants_hack [UIViewAutoresizingFlexibleHeight, UIViewAutoresizingFlexibleWidth, UIViewAutoresizingFlexibleTopMargin, etc] end end
  30. None
  31. • camelCase snake_case • NSNames Module::Names • isEnabled enabled? •

    setTitle #title= • .alloc.init .new • (Under the hood, still use designated initializer i.e. initWithFrame:, initWithNibNamed:bundle:)
  32. 0QFSBUPS 0WFSMPBEJOH

  33. []= HttpClient.headers["X-Authentication"] = "123123" class HttpClient class HeaderDSL def initialize(http_client)

    @http_client = http_client end def []=(header, value) @http_client.setDefaultHeader(header, value: value) end end def headers @header_dsl ||= HeaderDSL.new(self) end end
  34. << class NSOperationQueue def <<(operation) self.addOperation(operation) end end NSOperationQueue.currentQueue <<

    my_operation
  35. github.com/clayallsopp/geomotion size = CGSize.make(width: 50, height: 20) size + CGSize.make(width:

    100, height: 50) => CGSize(150, 70)
  36. alias_method

  37. class UIControl alias_method :enabled?, :isEnabled end my_button = UIButton.buttonWithType UIButtonTypeRoundedRect

    my_button.enabled?
  38. class NSOperationQueue class << self alias_method :current, :currentQueue end end

    OperationQueue = NSOperationQueue OperationQueue.current == NSOperationQueue.currentQueue
  39. .FUB 1SPHSBNNJOH

  40. 8IBUOFYU github.com/clayallsopp/rubymotion-wrappers rubymotion-wrappers.com/ @RM_Wrappers