Using blocks in Objective-C

One of my pious intentions for the year 2010 is to start writing some application for the Mac. Apart from the hype about iPhone development, I think that starting out in that area is especially appealing, as it reduces the size of the API one has to learn. Getting to know the iOS libraries is a lot easier than handling the endless amount of Cocoa frameworks.

One thing that I discovered recently is the support of blocks, that has been introduced with OSX 10.6 and iOS 4.0.

the environment matters

Consuming 3rd party data from the web is kind of a pain, especially compared to how easy it is in Ruby. So I was pleased to find Seriously, a framework for async calls and JSON/XML parsing. The Seriously examples made use of blocks:

NSString *url = @"";

[Seriously get:url handler:^(id body, NSHTTPURLResponse *response, NSError *error) {
    if (error) {
        NSLog(@"Error: %@", error);
    else {
        NSLog(@"Look, JSON is parsed into a dictionary!");
        NSLog(@"%@", [body objectForKey:@"profile_background_image_url"]);

Executing this example in my app code raised an error, that I could not easily understand:

"__NSConcreteGlobalBlock", referenced from: ___block_holder_tmp_1.1207 in DZoneController.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

The problem was, that XCode set my execution environment to OSX 10.5 which does not have support for blocks. To fix this, one has to update the MACOSX_DEPLOYMENT_TARGET build variable.

Right Clicking on the XCode project in the “Groups & Files” view will bring up a context menu with “Get Info” (or pressing CMD+I while project is selected). The info pane has a “General” tab that lets you select the “Base SDK for All Configurations”, which I set that to iOS 4.0.
An other option is to search for “MACOSX_DEPLOYMENT_TARGET” in the “Build” tab and changing that value accordingly. Make sure “Show” is set to “All Settings”.

At least some Objective-C sugar!