Search code examples
iosobjective-cjsonnsdictionarynsdata

Convert a JSON NSData to NSDictionary


I'm using an API service of a web service and it is written in their description that they send JSON data which also matches in my opinion with the response I get from it.

Here a part of it which I got from the NSURLConnection-Delegate (connection didReceiveData: (NSData *) data) and converted in a NSString using:

NSLog(@"response: %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);

Here the snippet:

{"scans": 
{
    "Engine1“: 
    {
        "detected": false, 
        "version": "1.3.0.4959", 
        "result": null, 
        "update": "20140521"
    }, 
    "Engine2“: 
    {
        "detected": false,
         "version": "12.0.250.0",
         "result": null,
         "update": "20140521"
    }, 
        ...
    },
    "Engine13": 
    {
         "detected": false,
         "version": "9.178.12155",
         "result": 

In the NSLog-String it stops there. Now I would like to know from you whats wrong that I can't convert this data to a JSON Dictionary with this lines of code:

NSError* error;
    NSMutableDictionary *dJSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];

I experiment with some options but always the same error:

Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" 
(Unexpected end of file while parsing object.) UserInfo=0x109260850 {NSDebugDescription=Unexpected end of file while parsing object.}

Everything indicates that the JSON packet is incomplete but I don't know how to check it or how to look for the issue which should be located in my code.


Solution

  • Did you implemented all the delegate methods of NSURLConnectionDelagate.It looks like you are taking the data for conversion from "- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data" delagate method. If so you may get incomplete data and that can not be converted.

    Try this:

    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
    {
        // A response has been received, this is where we initialize the instance var you created
        // so that we can append data to it in the didReceiveData method
        // Furthermore, this method is called each time there is a redirect so reinitializing it
        // also serves to clear it
        lookServerResponseData = [[NSMutableData alloc] init];
    }
    
    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
    {
        // Append the new data to the instance variable you declared
        [lookServerResponseData appendData:data];
    }
    
    
    - (void)connectionDidFinishLoading:(NSURLConnection *)connection
    {
        // The request is complete and data has been received
        // You can parse the stuff in your instance variable now
        NSError *errorJson=nil;
        NSDictionary* responseDict = [NSJSONSerialization JSONObjectWithData:lookServerResponseData options:kNilOptions error:&errorJson];
    
         NSLog(@"responseDict=%@",responseDict);
    
        [lookServerResponseData release];
        lookServerResponseData = nil;
    }
    

    Here, lookServerResponseData is instance of NSMutableData declared globally.

    Hope it will help.