Slide 1

Slide 1 text

@timriley I’m Tim Riley, I work at Icelab here in Canberra

Slide 2

Slide 2 text

Though I’ve just returned from 8 months in the Philippines. Some of the times, it was like this.

Slide 3

Slide 3 text

But most of the time, it was more like this.

Slide 4

Slide 4 text

But one thing that didn’t change was that I had a lot of this. And it’s the coffee drinking that’s kind of taken me to the point where I can talk to you guys today.

Slide 5

Slide 5 text

It was what led me to help build Decaf Sucks. It’s a Rails app, for café reviews.

Slide 6

Slide 6 text

Last year I build the native iOS app, in Objective-C. My first major iOS project.

Slide 7

Slide 7 text

And today I’ll talk about a bridge between these two worlds of tech: RubyMotion. So what is RubyMotion?

Slide 8

Slide 8 text

RubyMotion And today I’ll talk about a bridge between these two worlds of tech: RubyMotion. So what is RubyMotion?

Slide 9

Slide 9 text

RubyMotion is two things. First, a new implementation of Ruby integrated with the iOS runtime. Includes a static compiler that compiles Ruby into optimized machine code. This part’s proprietary. Second, a set of command line tools create, manage and interactively develop RubyMotion projects. Some of this has been recently open sourced.

Slide 10

Slide 10 text

"RubyMotion" "Objective-C" [@ isEqualToString: @ ]; Let’s compare. RubyMotion builds upon the foundation of Objective-C, starting with the basic object model. Both Ruby and Objective-C both have a common ancestor in Smalltalk, so there's a lot of similarities: Open classes, Single inheritance, Single dynamic message dispatch

Slide 11

Slide 11 text

"RubyMotion" "Objective-C" == Let’s compare. RubyMotion builds upon the foundation of Objective-C, starting with the basic object model. Both Ruby and Objective-C both have a common ancestor in Smalltalk, so there's a lot of similarities: Open classes, Single inheritance, Single dynamic message dispatch

Slide 12

Slide 12 text

[string drawAtPoint:point withFont:font]; Let’s start with message passing

Slide 13

Slide 13 text

string.drawAtPoint(point, withFont:font)

Slide 14

Slide 14 text

string.send(:'drawAtPoint:withFont:', point, font )

Slide 15

Slide 15 text

string.send(:'drawAtPoint:withFont:', point, font )

Slide 16

Slide 16 text

class DrawingProxy def drawAtPoint(point, withFont:font) @str.drawAtPoint(point, withFont:font) end end

Slide 17

Slide 17 text

.h Objective-C interface .h “header” files.

Slide 18

Slide 18 text

@class Foo - (id)instanceMethod; + (id)classMethod; @end One header for every class. We don’t need them any more. In Ruby, the class definitions are the class interfaces. In general, RubyMotion gets rid of a lot of the shitwork in Objective-C. No more repeating yourself.

Slide 19

Slide 19 text

One header for every class. We don’t need them any more. In Ruby, the class definitions are the class interfaces. In general, RubyMotion gets rid of a lot of the shitwork in Objective-C. No more repeating yourself.

Slide 20

Slide 20 text

Shortcuts

Slide 21

Slide 21 text

setFoo: foo=

Slide 22

Slide 22 text

isFoo foo?

Slide 23

Slide 23 text

objectForKey: []

Slide 24

Slide 24 text

setObject:forKey: []=

Slide 25

Slide 25 text

view.hidden = true unless view.hidden? Leads to the expressive Ruby code that we love.

Slide 26

Slide 26 text

Foundation Classes These classes are the base layer of the Cocoa and iOS libraries. RubyMotion translates these for you.

Slide 27

Slide 27 text

MyCustomClass NSObject Kernel

Slide 28

Slide 28 text

String NSMutableString NSString Comparable NSObject Kernel

Slide 29

Slide 29 text

Array NSMutableArray NSArray Enumerable NSObject Kernel

Slide 30

Slide 30 text

Hash NSMutableDictionary NSDictionary Enumerable NSObject Kernel

Slide 31

Slide 31 text

Numeric Comparable NSNumber NSValue NSObject Kernel

Slide 32

Slide 32 text

Time Comparable NSDate NSObject Kernel

Slide 33

Slide 33 text

'hello'.uppercaseString # => 'HELLO' Building upon the Foundation classes means you have access to their methods. Ruby's native interface for these classes still exists, implemented on their foundation counterparts (eg. NSArray#each). This means you can use the standard Ruby interface to these basic objects, regardless of their origin.

Slide 34

Slide 34 text

Mutable by Default eg., NSString vs NSMutableString. Be careful of the mutability of the objects returned by Cocoa methods.

Slide 35

Slide 35 text

Interfacing with C

Slide 36

Slide 36 text

bool BOOL C Types. RubyMotion translates these for you.

Slide 37

Slide 37 text

bool BOOL true false C Types. RubyMotion translates these for you.

Slide 38

Slide 38 text

char short int long long_long

Slide 39

Slide 39 text

long_long? Wait, long_long? What?

Slide 40

Slide 40 text

long_long? Wait, long_long? What?

Slide 41

Slide 41 text

char short int long long_long

Slide 42

Slide 42 text

char short int long long_long Fixnum Bignum

Slide 43

Slide 43 text

float double These translations are an improvement. Less for you to consider.

Slide 44

Slide 44 text

float double Float These translations are an improvement. Less for you to consider.

Slide 45

Slide 45 text

pt = CGPoint.new pt.x = 100 pt.y = 200 C Structures: a fixed set of labelled values in a single object. These are mapped to classes, which you can use in a number of ways, depending on your context. First, by named setter methods on an already instantiated object.

Slide 46

Slide 46 text

pt = CGPoint.new(100, 200) Or by ordered arguments during instantiation.

Slide 47

Slide 47 text

'Hello'.drawAtPoint(pt, withFont: font) Here’s how you’d pass that structure as a method argument

Slide 48

Slide 48 text

'Hello'.drawAtPoint([100, 200], withFont: font) Another shortcut: lets you use an array to pass the structure values in place.

Slide 49

Slide 49 text

'Hello'.drawAtPoint([100, 200], withFont: font) Another shortcut: lets you use an array to pass the structure values in place.

Slide 50

Slide 50 text

pt = CGMakePoint(100, 200) 'Hello'.drawAtPoint(pt, withFont: font) C Functions are available as methods of the Object class.

Slide 51

Slide 51 text

error_ptr = Pointer.new(:object) C Pointers. This is one time when you really feel that you're outside the comfort of Ruby. A Pointer is a memory address that can point to an object. In iOS SDK, typically used as arguments to return objects by reference.

Slide 52

Slide 52 text

- (id)addObserverForName:(NSString *)name object:(id)obj queue:(NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *))block; C Blocks. A new language extension from Apple.

Slide 53

Slide 53 text

notification_center.addObserverForName( name, object:object, queue:queue, usingBlock:lambda do |notification| # Handle notification here... end ) Should feel pretty natural to Rubyists. Use a Proc objects for the block argument.

Slide 54

Slide 54 text

notification_center.addObserverForName( name, object:object, queue:queue, usingBlock:lambda do |notification| # Handle notification here... end ) Should feel pretty natural to Rubyists. Use a Proc objects for the block argument.

Slide 55

Slide 55 text

Memory Management This is handled for you automatically. It uses a reference counting method, like ARC, but not exactly the same.

Slide 56

Slide 56 text

date = NSDate.alloc.init @date = date If you want to ensure an object's not released, you must create a reference to it, like setting an instance variable. Or set a constant, use a class variable, add the object to a container.

Slide 57

Slide 57 text

Enough with the theory. Let’s get some things up and running. Firstly, Installation: Get Xcode from the Mac App Store

Slide 58

Slide 58 text

Get the Command Line Tools from Xcode’s prefs.

Slide 59

Slide 59 text

Buy and install RubyMotion.

Slide 60

Slide 60 text

Hello world

Slide 61

Slide 61 text

A Bit of UIKit Let's make a more sophisticated hello world, with a UIViewController custom UIView subclass.

Slide 62

Slide 62 text

Interface Builder See http://ianp.org/2012/05/07/rubymotion-and-interface-builder/

Slide 63

Slide 63 text

gem install cocoapods pod setup gem install motion-cocoapods

Slide 64

Slide 64 text

require 'motion-cocoapods' Motion::Project::App.setup do |app| # ... app.pods do dependency 'JSONKit' end end Declare your pod dependencies in the Rakefile. You can also manually include Objective-C library dependencies using `app.vendor_project` directive. And `app.frameworks` allows control over which additional core iOS frameworks you want to use.

Slide 65

Slide 65 text

require 'motion-cocoapods' Motion::Project::App.setup do |app| # ... app.pods do dependency 'JSONKit' end end Declare your pod dependencies in the Rakefile. You can also manually include Objective-C library dependencies using `app.vendor_project` directive. And `app.frameworks` allows control over which additional core iOS frameworks you want to use.

Slide 66

Slide 66 text

RubyMotion Libraries So much innovation has taken place in just the last couple of months.

Slide 67

Slide 67 text

rubymotion/BubbleWrap

Slide 68

Slide 68 text

rubymotion/BubbleWrap

Slide 69

Slide 69 text

rubymotion/BubbleWrap

Slide 70

Slide 70 text

clayallsopp/Routable

Slide 71

Slide 71 text

alloy/MotionData

Slide 72

Slide 72 text

rubymotion/teacup

Slide 73

Slide 73 text

RubyMotion Benefits The expressiveness of Ruby (featured in the library examples we’ve just seen). For us, it’s also a language we already know.

Slide 74

Slide 74 text

describe "Application 'helloworld'" do before do @app = UIApplication.sharedApplication end it "has one window" do @app.windows.size.should == 1 end end Ruby’s strong testing tools and culture. RSpec is built-in.

Slide 75

Slide 75 text

You get to use your own tools. Opening up the toolset choices also means there’s room for innovation here. Think about all the convenience tools we have in Rails: guard, code coverage, testing tools, etc.

Slide 76

Slide 76 text

No more .xcodeproj bullshit. The project structure is simpler and neater, better for collaboration. The single Rakefile expresses your intent much more clearly.

Slide 77

Slide 77 text

No more .xcodeproj bullshit. The project structure is simpler and neater, better for collaboration. The single Rakefile expresses your intent much more clearly.

Slide 78

Slide 78 text

RubyMotion Costs

Slide 79

Slide 79 text

Your own tools aren’t likely as good at Cocoa as Xcode. Not yet, anyway.

Slide 80

Slide 80 text

I’ve spent a lot more time looking up docs in Dash.

Slide 81

Slide 81 text

It's not a magic bullet. You still have to learn iOS APIs.

Slide 82

Slide 82 text

RubyMotion Risks A major 3rd party dependency.

Slide 83

Slide 83 text

No content

Slide 84

Slide 84 text

The Future Ruby is a fantastic, enabling language. Will RubyMotion allow a "Rails" to evolve for iOS apps?

Slide 85

Slide 85 text

Learning More Free screencast at The Pragmatic Studio, RubyMotion example apps, List of known RubyMotion projects, Cocoa books and learning resources, Big Nerd Ranch examples.

Slide 86

Slide 86 text

@timriley Thanks