from Ruby to Objective-C
I’m a Flash guy (≈ 9 years) I’m a Python guy (≈ 3 years) I’m a Ruby guy (≈ 5 years) I’m a iOS app guy (≈ 3 years)
Ruby > Rails
Current Status 80% iOS app, 20% Ruby/Rails
100% Ruby Lover!
Rails Girls Taipei
Rails Girls Taipei
WebConf Taiwan 2014
Today, I’m NOT talking about.. how to use Ruby to write iOS app!
I’m going to talk about..
what I learned in Ruby…
and move to Objective-C
after all, our life, time and resources are limited
what about Objective-C?
Objective-C … “it has god dame long method name and weird parameters!” NSArray* languages = [NSArray arrayWithObjects:@"Ruby", @"PHP", @"Objective-C", nil]; ! [languages enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { NSLog(@"language = %@", obj); }];
Objective-C … “what the hell is the square bracket!” NSString* myName = @"eddie kao"; NSLog(@"%@", [myName uppercaseString]);
Objective-C … “WTF! my app crashed again!!”
Introduction
Ruby was born on 1993 Objective-C was born on 1983
they have the same ancestor
Smalltalk photo by Marcin Wichary
Ruby is general-purpose Objective-C mainly used in Mac/iOS app development
Ruby != Rails Objective-C != Cocoa Framework
they have something in common..
both Ruby and Objective-C are Object-Oriented
both Ruby and Objective-C are strongly typed language.
Ruby is a dynamic language Objective-C is a dynamic language
both Ruby and Objective-C are Dynamic Typing
Type checking.. - (void) makeSomeNoise:(id) sender { if ([sender isKindOfClass:[RobberDuck class]]) { RobberDuck* duck = (RobberDuck *) sender; [duck quack]; } }
or you can do this.. - (void) makeSomeNoise:(id) sender { if ([sender respondsToSelector:@selector(quack)]) { [sender quack]; } }
id
Objective-C is superset of C
Objective-C is still C
NSString, NSArray, NSNumber…
NextSTEP
CF… = Core Foundation CG… = Core Graphic CL… = Core Location CA… = Core Animation UI… = User Interface
OOP
everything in Ruby is an object…
and almost everything in Objective-C is an objects..
there’re still some primitive data types in Objective-C
object model class Animal end ! class Dog < Animal end
object model dog = Dog.new ! puts "class of dog is #{dog.class}” # Dog puts "superclass of dog is #{dog.class.superclass}” # Animal puts "super superclass of dog is #{dog.class.superclass.superclass}” # Object puts "super super superclass of dog is #{dog.class.superclass.superclass.superclass}” # BasicObject ! puts puts puts puts "class "class "class "class of Dog is #{Dog.class}” class of Dog is #{Dog.class.class}” of Animal is #{Animal.class}” of Object is #{Object.class}” # # # # Class Class Class Class
object model @interface Animal : NSObject @end ! @implementation Animal @end ! @interface Dog : Animal @end ! @implementation Dog @end
object model Dog* dog = [[Dog alloc] init]; ! NSLog(@"class of dog is %@", [dog class]); # Dog ! NSLog(@"superclass of dog is %@", [dog superclass]); # Animal ! NSLog(@"super superclass of dog is %@", [[dog superclass] superclass]); # NSObject ! NSLog(@"super super superclass of dog is %@", [[[dog superclass] superclass] superclass]); # null
Object Model reference: http://goo.gl/wYL6gT
method & message
method definition def say_hello(someone, message) puts "Hello #{someone}, #{message}" end - (void) sayHello:(id)someOne withMessage:(NSString *)message { NSLog(@"Hello %@, %@", someOne, message); }
sending message dog.walk() [dog walk]; # or you can omit the parentheses
sending message fox.say_something "hi, Ruby" [fox saySomething:@"hi, Ruby"]; # what does the fox say?
sending message puts 1 + 2 puts 1.+(2) puts 1.send(:+, 2)
sending message class Bank def save(money) puts "you just saved #{money} dollars" end end ! bank = Bank.new bank.save 20 bank.send(:save, 20) # you just saved 20 dollars # you just saved 20 dollars
sending message @interface Bank : NSObject - (void) save:(NSNumber *) money; @end ! @implementation Bank - (void)save:(NSNumber *)money { NSLog(@"you just saved %@ dollars", money); } @end ! Bank* bank = [[Bank alloc] init]; [bank save:@20]; [bank performSelector:@selector(save:) withObject:@20];
block
block p1 = Proc.new { puts "Hello, Proc Block" } p1.call ! p2 = lambda { puts "Hello, Lambda Block" } p2.call
block ^{ };
block typedef void (^MyBlock)(void); int age = 18; MyBlock theBlock = ^{ NSLog(@"Hello, Objective-C Block, your age = %d", age); }; ! theBlock(); # Hello, Objective-C Block, your age = 18 ! age = 38; theBlock(); # guess what’s the age?
block 3.times { |i| puts i } NSArray* list = @[@1, @2, @3]; [list enumerateObjectsUsingBlock:^(NSNumber* num, NSUInteger idx, BOOL *stop) { NSLog(@"%@", num); }];
iteration
iteration list = [1, 2, 3, 4, 5] ! sum = 0 ! list.each { |num| sum += num } ! puts "sum = #{sum}"
iteration NSArray* list = @[@1, @2, @3, @4, @5]; ! __block int sum = 0; ! [list enumerateObjectsUsingBlock:^(NSNumber* num, NSUInteger idx, BOOL *stop) { sum += [num intValue]; }]; ! NSLog(@"sum = %d", sum);
iteration class Fox def say puts "what does the fox say?" end end ! fox1 = Fox.new fox2 = Fox.new fox3 = Fox.new foxes = [fox1, fox2, fox3] ! foxes.map { |fox| fox.say } # what does the fox say?
iteration @interface Fox : NSObject - (void) say; @end ! @implementation Fox - (void) say { NSLog(@"what does the fox say?!"); } @end
iteration Fox* fox1 = [[Fox alloc] init]; Fox* fox2 = [[Fox alloc] init]; Fox* fox3 = [[Fox alloc] init]; ! NSArray* foxes = @[fox1, fox2, fox3]; ! [foxes makeObjectsPerformSelector:@selector(say)];
add methods at runtime
Open class class String def is_awesome? return true if self == "Ruby Tuesday" end end ! puts "Ruby Tuesday".is_awesome?
Category @interface NSString(RubyTuesday) - (BOOL) isAwesome; @end ! @implementation NSString(RubyTuesday) - (BOOL) isAwesome { if ([self isEqualToString:@"Ruby Tuesday"]){ return YES; } return NO; } @end
Category NSString* meetup = @"Ruby Tuesday"; if ([meetup isAwesome]) { NSLog(@"AWESOME!"); }
<objc/runtime.h> Working with Classes class_getName class_getSuperclass class_getInstanceVariable class_getClassVariable class_addIvar class_copyIvarList class_addMethod class_getInstanceMethod class_getClassMethod class_replaceMethod class_respondsToSelector .. reference: http://goo.gl/BEikIM
<objc/runtime.h> Working with Instances object_copy object_dispose object_setInstanceVariable object_getInstanceVariable object_getIndexedIvars object_getIvar object_setIvar object_getClassName object_getClass object_setClass .. reference: http://goo.gl/BEikIM
reflection - (BOOL) (BOOL) (BOOL) (BOOL) .. isKindOfClass:(Class) aClass isMemberOfClass:(Class) aClass respondsToSelector:(SEL) aSelector conformsToProtocol:(Protocol *) aProtocol reference: http://goo.gl/fgmJcg
ecosystem
open source projects on Github Ruby : 76,574 Objective-C : 22,959
Ruby : bundler source 'https://rubygems.org' ! gem 'rails', '3.2.8' gem 'mysql2' ! group :assets do gem 'sass-rails', '~> 3.2.3' gem "bootstrap-sass" end ! gem gem gem gem "kaminari" "simple_form" "carrierwave" 'unicorn'
Objective-C : cocoapods platform :ios, '6.0' ! pod pod pod pod pod pod 'Facebook-iOS-SDK', '~> 3.5.1’ 'JSONKit', '~> 1.5pre' 'MagicalRecord', '~> 2.0.7’ 'SSKeychain', '~> 0.1.4’ 'TestFlightSDK', '~> 1.1' 'SMCalloutView', '~> 1.1.2' ! target :UnitTests do link_with 'UnitTests' pod 'OCMock', '~> 2.0.1' pod 'OCHamcrest', '~> 1.9' end
IMHO
Objective-C is not really hard to learn…
the actual difficult part in iOS app development is Cocoa Framework
Objective-C would be almost useless without Cocoa Framework
Ruby without Rails?!
design patterns MVC observer notifications singleton delegation command composite target-action proxy
C
what else..
photoed by JD Hancock
Flash Display Hierarchy reference: http://goo.gl/2mzyMY
UIKit and AppKit framework Hierarchy reference: http://goo.gl/xhS7m7
Views reference: http://goo.gl/xhS7m7
Views reference: http://goo.gl/xhS7m7
and I read Ruby source code..
my iOS app dev experience = Ruby + C + Flash/AS3 = +
Contacts ⾼高⾒見⻯⿓龍 Website http://www.eddie.com.tw Blog http://blog.eddie.com.tw Plurk http://www.plurk.com/aquarianboy Facebook http://www.facebook.com/eddiekao Google Plus http://www.eddie.com.tw/+ Twitter https://twitter.com/#!/eddiekao Email eddie@digik.com.tw Mobile +886-928-617-687 photo by Eddie

from Ruby to Objective-C