Using Google AJAX search API in Cocoa
Sometimes it’s needed to allow user to find some information in the Web, without interrupting he/she from working with your application. In this small article I’ll describe simple solution to fulfill this task.
As for today, search = Google and I’m going to implement search using it. I’ve implemented category for Cocoa’s NSArray class for creating array of dictionaries. Each dictionary represents a search results. You can define where to search (web, news, video) etc and how many results to return. This code requires JSON Framework by Stig Brautaset
Here is the code of the main search method. The full project can be downloaded here (XCode 3.2, JSON Framework included)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | + (NSArray *)arrayWithSearchFor:(NSString *)query type:(NSString *)searchType range:(NSRange)range { if (range.location > 56) { NSLog(@"Error while searching in Google : start must be in range [0;56]"); return nil; } NSMutableArray *results = [NSMutableArray array]; SBJSON *parser = nil; NSString *json_string = nil; NSUInteger i = range.location; while (i < range.length + range.location) { @try { NSURL *url = [NSURL URLWithString:[BASE_URL stringByAppendingFormat:@"%@?v=%@&q=%@&start=%i", searchType, @"1.0", query, i]]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:120]; NSError *error = nil; NSURLResponse *response = nil; NSData *searchResults = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; if (!searchResults) { @throw [NSException exceptionWithName:@"Failed to search cuz: %@" reason:[error description] userInfo:nil]; } //parse results parser = [[SBJSON alloc] init]; json_string = [[NSString alloc] initWithData:searchResults encoding:NSUTF8StringEncoding]; //NSLog(@"Raw JSON result %@", json_string); NSDictionary *allResult = [parser objectWithString:json_string error:&error]; if (!allResult || [allResult isKindOfClass:[NSNull class]]) { @throw [NSException exceptionWithName:@"Failed to parse all results JSON" reason:[error description] userInfo:nil]; } if (![[allResult objectForKey:@"responseStatus"] isEqualToNumber:[NSNumber numberWithInt:200]]) { @throw [NSException exceptionWithName:[allResult objectForKey:@"responseStatus"] reason:[allResult objectForKey:@"responseDetails"] userInfo:nil]; } allResult = [allResult objectForKey:@"responseData"]; if (!allResult || [allResult isKindOfClass:[NSNull class]]) { @throw [NSException exceptionWithName:@"Failed to parse responseData" reason:[error description] userInfo:nil]; } NSArray *newResults = [allResult objectForKey:@"results"]; if (!newResults) { @throw [NSException exceptionWithName:@"Failed to parse results" reason:[error description] userInfo:nil]; } [results addObjectsFromArray:newResults]; i += SMALL_RESULT_SET; } @catch (NSException * e) { NSLog(@"Exception during searching in Google: %@", e); } @finally { [parser release]; [json_string release]; } } return results; } + (NSArray *)arrayWithWebSearchFor:(NSString *)query range:(NSRange)range { return [[self class] arrayWithSearchFor:query type:WEB_URL range:range]; } |
And the sample usage:
1 2 3 4 5 | NSArray *results = [NSArray arrayWithWebSearchFor:@"apple" range:NSMakeRange(0, 5)]; NSLog(@"Search finished, found %i", [results count]); for (NSDictionary *result in results) { NSLog(@"Url = %@", [result objectForKey:@"url"]); } |
In this sample code I’ve searched for “apple” and got the following results:
2009-10-13 01:18:40.638 iGoogle[63665:a0f] Url = http://en.wikipedia.org/wiki/Apple_Inc.
2009-10-13 01:18:40.641 iGoogle[63665:a0f] Url = http://www.info.apple.com/
2009-10-13 01:18:40.641 iGoogle[63665:a0f] Url = http://www.crunchbase.com/company/apple
2009-10-13 01:18:40.642 iGoogle[63665:a0f] Url = http://developer.apple.com/
2009-10-13 01:18:40.642 iGoogle[63665:a0f] Url = http://apple.slashdot.org/
2009-10-13 01:18:40.642 iGoogle[63665:a0f] Url = http://finance.yahoo.com/q%3Fs%3DAapl
2009-10-13 01:18:40.644 iGoogle[63665:a0f] Url = http://support.apple.com/batteryprogram/
2009-10-13 01:18:40.644 iGoogle[63665:a0f] Url = http://topics.nytimes.com/topics/news/business/companies/apple_computer_inc/index.html
This code has never been used in production, so use on your own risk
You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
![[Facebook]](http://ivira.name/blog/wp-content/plugins/bookmarkify/facebook.png)
![[Twitter]](http://ivira.name/blog/wp-content/plugins/bookmarkify/twitter.png)
![[Email]](http://ivira.name/blog/wp-content/plugins/bookmarkify/email.png)