NSJSONSerialization isValidJSONObject returns false for received data from Venue search endpoint
Asked Answered
L

2

2

Xcode 8.1 Deployment target iOS 9.0

I'm getting an array of compact venue objects as expected from Foursquare Venue Search endpoint in...

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data

When I check the data object using...

if ([NSJSONSerialization isValidJSONObject:data])

i get a false.

Can someone tell me what is wrong over here?

Edit: Here is the complete if block (after adding typecast to data in if block)...

    id foundationObject;

NSLog(@"data:- %@",data);
if ([NSJSONSerialization isValidJSONObject:(id)data])
{
    foundationObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
    NSLog(@"venues foundation object:- %@",foundationObject);
}

Earlier the code didn't have the if block. just...

id foundationObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];

The change was made when I realized (using breakpoint just after the above statement) that foundationObject was nil even though data wasn't.

Note: this worked fine earlier when I shipped my app for iOS 9.x in march. Could the version of the Venue Endpoint being called be making a difference?

Landlocked answered 16/11, 2016 at 15:30 Comment(0)
A
6

What you're testing here is for NSData. The input for isValidJSONObject is id not NSData

+ (BOOL)isValidJSONObject:(id)obj;

It returns YES if obj can be converted to JSON data (NSData), otherwise NO.

Also, according to documentation,

An object that may be converted to JSON must have the following properties:

  1. The top level object is an NSArray or NSDictionary.
  2. All objects are instances of NSString, NSNumber, NSArray, NSDictionary, or NSNull.
  3. All dictionary keys are instances of NSString.
  4. Numbers are not NaN or infinity.

Calling isValidJSONObject: or attempting a conversion are the definitive ways to tell if a given object can be converted to JSON data.

For converting NSData to JSONObject, you can use the following code

NSError *error;
id jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
if (!error) {
    // successfully done.
}else {
   NSLog(@"error: %@", error.localizedDescription)
}

Please note that to find out what's wrong with jsonData(NSData) you're receiving from the server, you have to pass NSError object into the method as shown in the above code. If conversion of NSData into jsonObject fails, you can find out why according to that.

Please look in to this link for more information on using NSError objects in Objective-C

Aloysius answered 16/11, 2016 at 15:38 Comment(7)
hello. i edited the question. please check. was already doing what you mentioned.Landlocked
Please check my answer. You're not doing what I mentioned in the answer. You are not passing NSError object in to the method. When you do that, you will get the error value which says what went wrong. I'll edit it to give you a clear cut answer to find where it went wrong.Aloysius
hi. this is the error i am getting... "JSON text did not start with array or object and option to allow fragments not set."Landlocked
i changed the reading option to "allow fragments" and i got ...error "Garbage at end."Landlocked
Check with your server side. Any JSON text should start with array or dictionary. I believe you can't just send plain text data from your server. Also, as apple says in the documentation, the top level object should be array or dictionary.Aloysius
i am calling foursqaure venues endpoint with code i wrote a year and a half back. i think they have changed the way to query their database. i cant find my client id and secret on their website.Landlocked
I think you have escape characters in your NSData. That might be one of the reasons for this.Aloysius
P
3

You are using a wrong method here isValidJSONObject will tell you whether JSON object (id) will be converted to JSON data or not.

As per the doc

Returns a Boolean value that indicates whether a given object can be converted to JSON data. YES if obj can be converted to JSON data, otherwise NO.

If you want to check Data then you should use JSONObjectWithData:options:error: and check if it is nil or not.

Edit

You need to first convert your Data to NSDictionary or NSArray like this

NSMutableDictionary * dict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];

then check if dict is a valid son or not like this

if([NSJSONSerialization isValidJSONObject:dict]){
    NSLog(@"dict is a valid JSON");
}else{
    NSLog(@"dict is not valid JSON");
}
Precipitancy answered 16/11, 2016 at 15:41 Comment(5)
please check the question again. i made an edit. was doing the same. however the object that captured the return value of JSONObjectWithData remains nil.Landlocked
@AceNeerav Updated my answerPrecipitancy
There's no point to checking isValidJSONObject after converting the data using JSONObjectWithData. If the data didn't represent a valid json object then JSONObjectWithData would return nil.Yaker
@AceNeerav You can't check NSData with isValidJSONObject check this - #17150368Precipitancy
saw the link. thanks. and i was expecting an error message but realized i had passed nil in error: parameter! (as pointed out Krishna)Landlocked

© 2022 - 2024 — McMap. All rights reserved.