Watch The Superbowl online

live superbowl stream

watch superbowl live

watch superbowl live

watch superbowl online

Watch The Superbowl online

SuperBowl

live superbowl stream

watch superbowl online

SuperBowl


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.

  • Zn

    Вопрос. Почему json`вский парсер не переваривает ответ с
    http://www.google.com/finance/match?q=apple

  • http://www.vera.org.ua vira

    Этот JSON содержит эскейп-последовательности, которые парсер не понимает (баги даже открытые есть http://code.google.com/p/json-framework/issues/detail?id=46). В данном случае, он вроде бы не воспринимает эскейп-последовательность \x27.
    Мой маленький фикс класса SBJsonParser помог ему распарсить, но с некрасивыми значениями порой (напр. “Berry, Appleman x26 Leiden LLP”).

    Возможный “фикс”: в методе – (BOOL)scanRestOfString:(NSMutableString **)o добавить в switch case 0×78: после case ‘”‘:.