parsing NSJSONReadingAllowFragments

2019-01-28 06:26发布

问题:

I am receiving some json data in my app:

NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:jsonResponse options:NSJSONReadingAllowFragments error:nil];
        NSLog(@"json :%@", json);

which logs:

json :{
  "email" : "/apex/emailAttachment?documentId=00PZ0000000zAgSMAU&recipientId=003Z000000XzHmJIAV&relatedObjectId=a09Z00000036kc8IAA&subject=Pricing+Comparison"
}

This is exactly what I want.

However, when I go to read the value of the email by doing

[json objectForKey:@"email"]

I receive an invalid argument exception:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[NSDictionary initWithDictionary:copyItems:]: dictionary argument is not an NSDictionary'

How can I read this value?

回答1:

It seems that your server sends "nested JSON": jsonResponse is a JSON string (not a dictionary). The value of that string is again JSON data representing a dictionary.

In that case you have to de-serialize the JSON twice:

NSString *jsonString = [NSJSONSerialization JSONObjectWithData:jsonResponse options:NSJSONReadingAllowFragments error:nil];
NSData *innerJson = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:innerJson options:0 error:nil];

NSString *email = jsonDict[@"email"];


回答2:

the 'json' object is obviously not a dictionary hence the error.

you are passing the NSJSONReadingAllowFragments flag to JSONObjectWithData:options:error: which says:

Specifies that the parser should allow top-level objects that are not an instance of NSArray or NSDictionary.

you need to check the class type of the object returned from the method.

Additionally you are under the false impression that you would get a mutable instance from the method call. If you want a mutable instance to be returned you need to use NSJSONReadingMutableContainers for mutable arrays/dics or NSJSONReadingMutableLeaves for mutable strings