Search code examples
swiftjsonpafnetworking-2

Using CDLJSONPResponseSerializer to hande JSONP in AFNetworking 2.0 in Swift


Need help trying to use AFNetworking to access this JSONP data:

http://chartapi.finance.yahoo.com/instrument/1.1/AAPL/chartdata;type=close;range=1d/json/

I used the CDLJSONPResponseSerializer found here:

https://github.com/clundie/CDLJSONPResponseSerializer

My code produces "Error: The JSONP response was invalid":

let manager = AFHTTPRequestOperationManager()
        manager.responseSerializer = CDLJSONPResponseSerializer()

        manager.GET( "http://chartapi.finance.yahoo.com/instrument/1.1/AAPL/chartdata;type=close;range=1d/json/",
            parameters: nil,
            success: { (operation: AFHTTPRequestOperation!,responseObject: AnyObject!) in
                println("JSON: " + responseObject.description)

            },
            failure: { (operation: AFHTTPRequestOperation!,error: NSError!) in
                println("Error: " + error.localizedDescription)
            })

Solution

  • The returned string is not JSON, it has a function wrapper: "finance_charts_json_callback(" ... "). That needs too be removed prior to de-serializing the JSON into a dictionary.

    Here is "proof of concept" code in Objective-C:
    Note 1: The concept is the same in Swift.
    Note 2: There is no error checking, POC only.

    NSString *urlString = @"http://chartapi.finance.yahoo.com/instrument/1.1/AAPL/chartdata;type=close;range=1d/json/";
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
    NSURLResponse *response;
    NSData *jsonData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:NULL];
    
    NSData *prefixData1  = [@"(" dataUsingEncoding:NSUTF8StringEncoding];
    NSRange prefixRange1 = [jsonData rangeOfData:prefixData1 options:0 range:NSMakeRange(0, jsonData.length)];
    NSData *suffixData   = [@")" dataUsingEncoding:NSUTF8StringEncoding];
    NSRange suffixRange  = [jsonData rangeOfData:suffixData options:NSDataSearchBackwards range:NSMakeRange(0, jsonData.length)];
    NSRange range = NSMakeRange(prefixRange1.location+1, jsonData.length - prefixRange1.location - 1 - suffixRange.length);
    
    jsonData = [jsonData subdataWithRange:range];
    NSDictionary *d = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];
    NSLog(@"d: %@", d);