If You Want to Learn Cocoa...

…be prepared to write a lot more code than in your typical “scripting” language. Three examples (I am using Ruby for comparison because it is the scripting language I am most familiar with; things would look very much the same with Python or PHP):

1. Declare a small hash/dictionary of key-value pairs


person = {
  :name => "John Appleseed",
  :age => 30,
  :favorite_fruit => [ "apple", "banana", "kiwi" ]


NSDictionary *person = [NSDictionary dictionaryWithObjectsAndKeys:
                        @"John Appleseed", @"name",
                        [NSNumber numberWithInteger:30], @"age",
                        [NSArray arrayWithObjects:@"apple", @"banana", @"kiwi", nil], @"favoriteFruit",

Now which of these is easier to read?

2. What day of the month is today?


today = Date.today                       # => #
puts "Day of the month: %d" % today.day  # => Day of the month: 7


NSDate *today = [NSDate date];                        // => 2010-03-07 15:15:26 +0100
NSCalendar *calendar = [NSCalendar currentCalendar];  // => <__NSCFCalendar: 0x100400160>
NSDateComponents *components = [calendar components:NSDayCalendarUnit
NSLog(@"Day of the month: %d", [components day]);     // => Day of the month: 7

3. Fetch something from the data store

Ruby on Rails (Active Record):

result = Person.find(:all, :conditions => { :first_name => "John" }, :order => "created_at DESC")

Cocoa (Core Data):

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"firstName == %@", @"John"];
[fetchRequest setPredicate:predicate];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"creationDate" ascending:NO];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];

NSError *fetchError = nil;
NSArray *fetchResult = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
[fetchRequest release];

Now I know this is not a fair comparison, Objective-C/Cocoa has many advantages over Ruby et al., you can’t compare Core Data to Active Record, etc. Still, I find the differences very striking, especially regarding the readability of the code.