We use excellent Three20 framework in most of our iPhone projects. One of the great things provided by it is convenient framework for making HTTP requests to web services. There are plugins available to parse both JSON and XML responses. However for one of the projects I needed to parse JSONP response and I haven’t found any ready to use solution.

So I decided to make my own implementation of JSONP response parser, based on available TTURLJSONResponse class. Here it goes:

@implementation JSONPResponse

// This method is based on the same-named method in TTURLJSONResponse
// Note, that only SBJSON suport is left
- (NSError *) request: (TTURLRequest *) request processResponse: (NSHTTPURLResponse *) response
                 data: (id) data {

    // This response is designed for NSData objects, so if we get anything else it's probably a
    // mistake.
    TTDASSERT([data isKindOfClass: [NSData class]]);
    TTDASSERT(nil == _rootObject);
    NSError *err = nil;
    if ([data isKindOfClass: [NSData class]]) {
        NSString *json = [[[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding] autorelease];

        // Remove JSONP wrapper

        json = [json stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
        NSRange openingBracket = [json rangeOfString: @"("];
        NSRange closingBracket = [json rangeOfString: @")" options: NSBackwardsSearch];

        if (openingBracket.location != NSNotFound && closingBracket.location != NSNotFound) {
            json = [json substringWithRange:
                    NSMakeRange(openingBracket.location + 1, closingBracket.location - openingBracket.location - 1)];

            // Parse JSON
            _rootObject = [[json JSONValue] retain];

        // Report error if failed to parse
        if (!_rootObject) {
            err = [NSError errorWithDomain: kTTExtJSONErrorDomain
                                      code: kTTExtJSONErrorCodeInvalidJSON
                                  userInfo: nil];

    return err;


Full source code is available as Gist: https://gist.github.com/1052330