huddie96
huddie96

Reputation: 1278

Convert NSData from NSURLSession to JSON

I am aware that there are many similar SO questions that have a similar title to mine. I have checked them out and am still running into this problem.

I am trying to access an API that returns a string that should/could be formatted as JSON.

To retrieve this string as convert the string to JSON I'm using (unsuccessfully) this code:

NSError *error;

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request
                                            completionHandler:
                                  ^(NSData *data, NSURLResponse *response, NSError *error) {

                                NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

                                      NSLog(@"Response: %@",responseString);


                                      NSData *jsonData = [responseString dataUsingEncoding:NSUTF8StringEncoding];

                                      id json = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];

                                      NSLog(@"%@",[json objectForKey:@"ID"]);


                                      NSLog(@"Json: %@",json);

                                  }];



    [task resume];

The NSLog(@"Response:...) returns a string that when I enter it into this website: http://jsonviewer.stack.hu confirms that the string is valid JSON.

Both NSLog's that are supposed to return a JSON value come back null.

What iv'e tried:

I have also now tried:

 NSURLRequest *request = [NSURLRequest requestWithURL:url];

    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request
                                            completionHandler:
                                  ^(NSData *data, NSURLResponse *response, NSError *error) {


                                      NSMutableDictionary *jsonObject;

                                      NSError *err = nil;
                                      @try
                                      {
                                          jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&err];
                                      }
                                      @catch (NSException *exception)
                                      {
                                          NSLog( @"Exception caught %@",exception);
                                      }

                                      NSDictionary *info = jsonObject;

                                      NSLog(@"Json: %@",info);

                                  }];



    [task resume];

What am I doing wrong here? How can I get a NSDictionary (JSON) result.

Upvotes: 0

Views: 950

Answers (2)

Larme
Larme

Reputation: 26096

Your main issue:
If you read the error parameter of +JSONObjectWithData:options:error:, it will tell you this:

Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}

As stated, your answer looks like this: aStringKey = realAndValidJSONSurroundedByCurvyBrackets, which is not a valid JSON. After discussion in chat, you have contact with the server side, and it should be their responsibility to give proper JSON. Until they fix it, in order to keep working, you can do:

NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
str = [str stringByReplacingCharactersInRange:NSMakeRange(0, [@"aStringKey = " length] ) withString:@""];
NSError *jsonError = nil;
NSDictionary *jsonFinal = [NSJSONSerialization JSONObjectWithData:[str dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&jsonError];

if (jsonError)
{
    NSLog(@"Error: %@", jsonError);
}

But remember, that's a "quick hack/fix" and shouldn't be left in final version and remove as soon as possible.

You tried:

NSError *err = nil;
@try
{
    jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&err];
}
@catch (NSException *exception)
{
    NSLog( @"Exception caught %@",exception);
}

The @try{}@catch(NSException *exception) shouldn't work since +JSONObjectWithData:options:error: shouldn't throw a NSException in your case, so in theory, there is nothing to catch, and but it may still not work (since there is a NSError). Of course, since data parameter should be non null, if it's nil, you'll get a NSException (which would log Exception caught data parameter is nil), but that's another issue and doesn't assure you that the parsing went wrong (because of invalid JSON like in our case) if there is no exception.

Upvotes: 2

Minkle Garg
Minkle Garg

Reputation: 751

Try this:

  NSMutableDictionary *jsonObject;

    NSError *err = nil;
    @try
    {
        jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&err];
    }
    @catch (NSException *exception)
    {
        NSLog( @"Exception caught %@",exception);
    }

    NSDictionary *info = jsonObject;

Upvotes: 1

Related Questions