Cocoa Developer, London UK

NSURLConnection setDelegateQueue is broken on iOS

Dec 29 2011

On Mac OS 10.7 and iOS 5.0, a very handy method has been added to NSURLConnection: setDelegateQueue:.

Using a URL connection in an NSOperation subclass has always been quite tedious because of the fact that one has to run a runloop for as long as the delegate callbacks have to happen. As suggested by Marcus Zarra in this StackOverflow answer, this has usually been achieved by calling CFRunLoopRun() when calling the start: method on NSURLConnection and CFRunLoopStop(CFRunLoopGetCurrent()) when the connection finishes loading or fails.

However, as my colleague Keith Duncan pointed out on CocoaBuilder, this is not optimal and should be avoided.

So, by creating an NSOperationQueue in your NSOperation subclass and scheduling the delegate callbacks into this queue, we do not need to run the current runloop for the length of the operation and consume a thread. In a nutshell, this is very handy and a much cleaner way to achieve this!

Here comes the problem: even though everything works perfectly fine on Lion, when performing the very same thing on iOS, the delegate callbacks are never called. It looks like the connection has to be started (and the delegate queue set) on the main queue for the delegate callbacks to happen. This obviously defeats the point of using it within an NSOperation subclass given that since Snow Leopard (and iOS 4.0) the start method of NSOperation will likely not be called on the main thread.

For this reason, in my opinion, the setDelegateQueue: method is unusable as per iOS 5.0 and should be avoided until Apple fixes this problem.

I have filed a bug at rdar://10529053 and you should dupe it if you observe the same behavior as I do.

I have created a small sample project to demonstrate the bug that I have attached to the radar. Feel free to run it on your side and see for yourself. You can download it from here.

MIME type to UTI and back again in Cocoa

Dec 28 2011

Often when working with web services in Cocoa, I need to convert between MIME type and Uniform Type Identifier (UTI).

I have seen many hacky way to do this but, in my opinion, following is the correct way to achieve it.

First let's import the appropriate framework based on the platform (you might also need to add the framework to your project if not previously done).

#if TARGET_OS_IPHONE
#import <MobileCoreServices/MobileCoreServices.h>
#else
#import <CoreServices/CoreServices.h>
#endif

To get the UTI from a MIME type.

NSURLResponse *response = ... // assume a URL response from somewhere else.
NSString *responseMIMEType = [response MIMEType];
CFStringRef MIMEType = (__bridge CFStringRef)[response MIMEType];
CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, MIMEType, NULL);
NSString *UTIString = (__bridge_transfer NSString *)UTI;

And to get the MIME type from the UTI.

NSString *filePath = ... // assume the path to a file from somewhere else.
CFStringRef fileExtension = (__bridge CFStringRef)[filePath pathExtension];
CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, NULL);
CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType);
CFRelease(UTI);
NSString *MIMETypeString = (__bridge_transfer NSString *)MIMEType;

Recursive Blocks in Objective-C

Oct 29 2011

Blocks are an awesome feature added to Objective-C with Mac OS X 10.6 and iOS 4.0.

Most of the Cocoa API now includes block-based alternatives and some new APIs (like the AssetsLibrary framework for example) are only based on blocks. So you do not have a choice anymore, you have to use blocks.

One cool feature that you might run into is recursive blocks. Even if there is in fact no reason why a block could not be recursive, there are a couple of rules to follow. An example of a recursive block would be something like the following:

void (^blocky) ();
blocky = ^ void (){
    blocky();
};
blocky();

Note that this piece of code has a couple of problems, apart from the fact that it loops forever, but explaining them being the point of this post we will discuss them later (no spoilers!).

So why would we ever want to use a block recursively? Well, think about a common pattern in Cocoa, particularly in CocoaTouch. You have a UINavigationController on which you push instances of subclasses of UITableViewController in order to display some sort of tree structure of data. This structure will most likely be fetched from Core Data and resides in a single place in your application, probably in the root view controller of your navigation controller.

Now suppose that each of these instances of (subclasses of) UITableViewController has to perform a specific action when one of its cells is clicked. It could be modifying the cell, pushing a new UITableViewController on the navigation stack or even do nothing. Since, as we have seen, the whole data structures would be owned by a single object (the root view controller), you do not really want controller down the stack to have to decide what to do with this data. You would rather have the root view controller, that actually manages the data, react to events down the chain.

You could have a simple protocol in your UITableViewController subclass that the root view controller would conform to but you would end up with your logic for cell selection handling residing in two spots: in the table view cell selection callback in your root view controller and in the table view controller subclass delegate methods in this very same root view controller.

So why not having a block that handles the cell selection in the root view controller and passing this block down the stack. Once a cell down the navigation controller is clicked, the controller subclass simply invokes that block and the root view controller will perform anything it has to do at that stage.

So let's write some (pseudo)code. First, assume that we will use the same subclass of UITableViewController for any level of navigation down the stack. At the end, it probably will display the same kind of data so why create a custom subclass for each level of navigation. We will also have a simple class representing a data object to be displayed. Think about it as the data backing up the content of your cells. These objects are probably organized in an NSArray that itself resides in the root view controller. Each data object has a children array containing other data objects further down in the data hierarchy.

First the very elementary MyDataObject class:

@interface MyDataObject : NSObject

@property (strong) NSArray children;

@end

@implementation MyDataObject

@synthesize children = _children;

@end

Next, the UITableViewController subclass used to manage the table view used to display content down the navigation stack:

typedef void (^CellSelectionHandlerBlock)(MyDataObject clickedItem);

@interface MyTableViewControllerSubclass : UITableViewController

@property (strong) MyDataObject dataObject;
@property (copy) CellSelectionHandlerBlock selectionHandlerBlock;

@end

@implementation MyTableViewControllerSubclass

@synthesize dataObject = _dataObject;
@synthesize selectionHandlerBlock = _selectionHandlerBlock;

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (_selectionHandlerBlock != NULL)
    {
        MyDataObject *clickedDataObject = [[[self dataObject] children] objectAtIndex: [indexPath row]];
        _selectionHandlerBlock(clickedDataObject);
    }
}

// some other methods, in particular UITableView dataSource and delegate

@end

And finally the root view controller, itself a subclass of UITableViewController, that manages the table view used at the first level of hierarchy. It also manages the data objects and handle the cell selection in both its own table view and down the stack:

@interface MyRootTableViewController : UITableViewController

@property (strong) NSArray *dataObjects;

@end

@implementation MyRootTableViewController

@synthesize dataObjects = _dataObjects;

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    CellSelectionHandlerBlock selectionHandlerBlock = nil;
    selectionHandlerBlock = ^ void (MyDataObject clickedItem) {
        if ([[clickedItem children] count] > 0)
        {
            MyTableViewControllerSubclass *viewController = [[MyTableViewControllerSubclass alloc] init];
            [viewController setDataObject: clickedItem];
            [viewController setSelectionHandlerBlock: selectionHandlerBlock]
            [[self navigationController] pushViewController: viewController animated: YES];
        }
        else
        {
            NSLog(@"Do some funky stuff with the cell!");
            // like presenting a modal view controller with some content.
        }
    }
    
    MyDataObject *dataObject = [[self dataObjects] objectAtIndex: [indexPath row]];
    selectionHandlerBlock(dataObject);
}

// some other methods, in particular UITableView dataSource and delegate

@end

So as you can see, we only need to write the selection handling code once. In function of the data object underlying the clicked cell, the root view controller create a new MyTableViewControllerSubclass with the appropriate data object and pass the selection handler block to it. Whenever a cell is clicked in a view controller down the stack, we first retrieve the data object corresponding to the clicked cell and invoke the block.

Also, every time a table view cell is clicked in the root view controller itself, the very same block is invoked.

However, this piece of code creating the block is wrong for two reasons that I am going to explain. As you can see, the block is recursively called inside the block itself. In order to explain the problems with the current approach, let's get back to our simpler blocky example.
In this example, a block is created and then called inside the content of the block creating infinite recursion. Leaving aside the infinite part here, this piece of code would crash on the first recursive call. To understand why, let's first discuss how a block treats its enclosing scope variables. Consider the following example:

int i = 1;
void (^block) () = ^ void () {
    NSLog(@"i = %i", i);
    i++;
};

This piece of code would correctly print i = 1 but would crash on the second line i++. The reason is that the block captures local variables in its scope and treat them as constant.
In the case of Objective-C objects, captured objects are retained (and automatically released when the block goes away).
Blocks are actually Objective-C objects themselves. When first created, a block lives on the stack. If you intend to use the block beyond the current scope, you need to copy it to the heap. Once the block has been copied to the heap, it can be retained and released as a regular object (it does not make sense to retain a stack-based block though).
In order for a block to change its enclosing scope, we can use the __block storage type. Consider the following example:

__block int i = 1;
void (^block) () = ^ void () {
    NSLog(@"i = %i", i);
    i++;
    NSLog(@"i = %i", i);
};

In this case, the program will run correctly and print i = 1 and i = 2. The block was able to modify the variable in its enclosing scope. Also note that __block captured objects are not retained.

So coming back to our blocky example, we now understands better why the crash is occurring. Since the block itself is invoked inside the block, it is const copied even before the assignment occurs. We can fix this by rewriting the program as:

__block void (^blocky) ();
blocky = ^ void (){
    blocky();
};
blocky();

Similarly, in our navigation controller example, we would have to rewrite:

__block CellSelectionHandlerBlock selectionHandlerBlock = nil;
selectionHandlerBlock = ^ void (MyDataObject clickedItem) {
    ...
}

So far so good, and to be honest, during my testing, I did not have to do anything else for this to run perfectly in Debug mode. However, the first time I ran it in Release mode, my program crashed on the block invocation. It took me a while to understand what was going on until I realized that there was a small problem here.
I was reusing my block outside the current scope and even copied it later on (when passed to another objects).
If you think about it, the first block that is assigned to the __block type variable is a stack-based block. The block that is called inside the block is this very same stack-based block.
When the block is moved to the heap, captured variable are moved to the heap too. So our block variable is moved to the heap once the block is copied so we need to make sure that the reference variable points to the copy of the block and not the original stack-based one.

The solution to this problem is to copy the block while creating it and assign this copied version to our __block variable:

__block void (^blocky) ();
blocky = [^ void (){
    blocky();
} copy];
blocky();

I have no idea why this was not crashing in Debug.

Blocks are very handy but are a tricky concept to grasp at first. However, there are a very powerful tool and I can only tell you that once you go block you never go bock (sorry, that was lame).

I definitely recommend the following articles and books to learn more:

Min Nya Fjällräven Kånken

Oct 27 2011

Yesterday I received my new laptop bag. I am really satisfied with it so I thought I would share my story.

Deciding on a bag is tricky. It's quite hard to find an item that matches your criteria for appearance, comfort and usability.

Since high school, I have been using a DJ bag form Manhattan Portage in black. It fits perfectly a 15'' laptop. I used it through most of university and have been quite happy with it. When I got my first 13'' MacBook, I logically got another bag from Manhattan Portage, a School Backpack that fits a 13'' laptop (and has a special compartment for it). I have been using this bag for a few years and absolutely loved it.

Last year, my girlfriend gave me a Swedish bag apparently quite trendy over there, a Fjällräven Kånken, the classic model in red. This bag is very fun, comfy and of very (very!) good quality (this was a second hand for I don't know which year but sincerely, I wouldn't know how to break the damn thing!). It fits a 13'' laptop quite alright, even if there is no special pocket for the laptop. I have used it for nearly a year and enjoyed it a lot. I also used it as my every day bag when my girlfriend and I went on a trip one month in Brazil last May and it's been a great companion!

However, when I got a 15'' MacBook Pro, I was not able to use it anymore so I had to get back to my DJ bag and outch! I forgot how uncomfortable a shoulder bag is versus a backpack. So I had to hunt for a new bag.

Tough times.. I couldn't decide on a model that I found attractive and that would take great care of my laptop (and my back). Until I realized that Fjällräven Kånken were not only doing the classic model but had recently released a 15'' laptop backpack. So I got one in black. It basically matches the appearance of the classic but is a bit bigger and also have a special back pocket for the laptop. You can thus use the front part of the bag as you would do with a normal bag but you have extra storage specially for your laptop against your back (the pocket actually matches perfectly the 15'' MackBook Pro so I guess they designed the bag with this laptop in mind). The back pocket is sensational; enough saying that it's the first time I dare putting my laptop into a bag without a sleeve (the laptop + the sleeve wouldn't fit in the back pocket anyway).

I highly recommend this bag. If you are interested, they also do the laptop backpack model for 13'' and 17'', just check their store.

My Backup Solution

Aug 11 2011

I recently decided to have a serious look at my backup strategy.
For the past few years, I have simply been using a Time Machine hard disk that I have been trying to plug to my laptop at least daily. I have also been keeping my code in sync to GitHub as much as possible.

Given that my Time Machine hard disk is sitting on my desk, this backup solution is not very robust since in case of fire or theft (knock on wood!), I would not be protected at all. My code would surely be easily to get back from GitHub but I write way more code than I can host in my private repositories on GitHub. Thus, I decided to take a step forward and here is my current backup strategy:

  • Time Machine: I own a Western Digital 2TB hard drive which is partitioned into two 1TB parts, one of them being exclusively for Time Machine (I store mainly media on the second half). It supports Firewire 800 which makes Time Machine backups super fast with my Macbook Pro. I try to keep it plugged to the MBP as much as possible during the day but I make sure that it’s plugged at least once everyday, most of the time at night.

  • Dropbox: My main Documents folder is pretty much empty since I use Dropbox for my documents. All my work related stuff, old university coursework and notes, photos are also stored on Dropbox. Having multiple computers, I use Dropbox extensively and am very happy with it. I pay $9.99/month for 50GB and I seriously think it is a bargain given the quality of the service.
    I have also set up a Library folder in my root folder where I store Application Support data for various applications that I want to access from multiple computers such as 1 Password, Things, Papers and MoneyWell.
    Finally, I have a Code Collection folder where I store code samples I found around the Internet or small projects I have been messing around and that do not require a proper version control.

  • Amazon S3: I currently use Arq.app for uploading hourly backups of my drive to Amazon S3 storage. Arq is an excellent software and I’m extremely happy with it. It uploads in the background through an agent (Arg Agent) and is pretty fast. The backups are also encrypted which is a very neat feature.
    I have opted for an Amazon S3 monthly budget of $5 which gives me 53.76GB of storage and seems to meet my space requirements. Also, Amazon recently made the data transfer-in free so there is no fee for uploading the backups to S3. Data transfer-out still costs a few cents per GB but this should rarely happen giving that the data is a backup. As you understood, the total monthly cost is mainly the storage.
    It is recommended to backup the whole User directory but I preferred to pick the folders to backup manually. Note that I have an extensive Music folder (over 100GB) that for obvious reasons I do not backup to S3. It is however part of my Time Machine backup and I hope to be able to transfer it to the cloud soon once iTunes offers it. If it did not happen this fall, I might decide to back it up to S3 though.
    The folders that I backup are thus as following:

    • /Library/Application Support
    • /Applications
    • ~/Desktop
    • ~/Documents
    • ~/Dropbox
    • ~/Library (excluding Caches and Logs)
    • ~/Movies
    • ~/Pictures/iPhoto Library
  • GitHub: I have a GitHub micro plan ($7/month) which allows me to keep up to 5 private repositories. My main projects are stored on GitHub. I have added the public keys associated to my various machines to GitHub which allows me to push and pull from any of my computers. I am extremely happy with GitHub since the first day I have started using it!

  • Gitosis on Linode: I have a Linode VPS that I use to store my websites, web services and messing around. I have setup a Git “server” with Gitosis and there I store any project that requires Version Control but not important enough to be a proper private repository on GitHub. Setting up Gitosis was a bit of a pain on the ass but now that it is up and working, I am quite satisfied. Similarly, I have uploaded the public keys of my various machines to be able to push and pull.

I am now fairly confident with my backups. I am easily able to revert changes locally with Time Machine or even from the cloud with Arq (both these backups are done hourly).
In case of hard disk failure or theft on my Macbook Pro, I can easily restore the whole disk from Time Machine.
In case my Time Machine hard disk is also corrupted, I can now restore my main files and configuration from Amazon S3 with Arq.
Every piece of code I write is also version controlled so reverting mistakes is trivial.