noizZze

iPhone: Background Lookup and Dictionaries

First of all, for those who don’t follow me on twitter (@spyromus), this year I’m working on my Cocoa / Cocoa Touch skills. Love it immensely so far and especially how things are nicely done in the iPhone department. A sheer pleasure.

During the last few weeks I tried several iPhone dictionaries and surprisingly all of them ( I mean ALL ) are coded in a strange way. The one of the most important parts – word entry – is implemented in a totally unimaginative straightforward way where it either looks up whatever you enter against their huge databases after every new letter or does that periodically. Both versions block the search box every now and then and don’t let you enter your searches quickly.

No finger pointing here certainly, but you guys know who you are. I tried to contact authors and share this bit of knowledge, but it’s either http://localhost/ as the support link or no link at all, so… the least I can do is to share it here. Hope it’ll be of some help.

Here’s the part of a XYZViewController:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- (void)viewDidLoad {
  operationQueue = [NSOperationQueue new];
  [super viewDidLoad];
}

- (void)searchBar:(UISearchBar *)searchBar
    textDidChange:(NSString *)searchText {
  [operationQueue cancelAllOperations];

  SearchOperation *op = [[SearchOperation alloc]
    initWithText:searchText dictionary:dictionary controller:self];

  [operationQueue addOperation:op];
  [op release];
}

Where SearchOperation is a subclass of NSOperation and its main method looks something like this:

1
2
3
4
5
6
7
8
9
10
- (void) main {
  [NSThread sleepForTimeInterval: 0.25f];

  if (![self isCancelled]) {
    // Do your searching magic here ...
    [controller performSelectorOnMainThread:@selector(searchResult:)
      withObject:...
      waitUntilDone:NO];
  }
}

The idea is that when the user types a letter, the searchBar:textDidChange: is called, but it doesn’t do the search right away. Instead it creates an instance of the SearchOperation which represents a lengthy dictionary lookup and queues it. Each SearchOperation sleeps 1/4 seconds before it starts doing any work. In fact, before the actual start it checks if it was canceled and does that periodically during the search.

So when it can be canceled? That’s why we have the cancelAllOperations call in the queuing code. If the user types, every next letter results in the cancellation of previous search operations and none of them will complete or even start. Moreover, the user interface will never be blocked and your users can type away freely and only if they stop, the GUI will follow and show the results.

You see? Simple.