Why is this JSON invalid using NSJSONSerialization? - ios

I'm new to JSON and don't understand why this is failing. The JSON is valid according to on-line validation tools, but NSJSONSerilization says this the string is invalid. Why is it invalid?
NSString* JSON = #"{\"Questionnaire\":{\"questionnaireid\":1,\"modifiedDate\":\"2012-12-28 15:27:00\"}}";
if (![NSJSONSerialization isValidJSONObject:JSON]) {
return nil;
}
NSError *jsonParsingError = nil;
NSDictionary* data = [NSJSONSerialization dataWithJSONObject:JSON options:NSJSONReadingMutableContainers error:&jsonParsingError];

why you did serialization when you already created JSON yourself ?
What you should do:
NSData *jsonPayload = [JSON dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *data = [NSJSONSerialization JSONObjectWithData:jsonPayload
options:kNilOptions error:&error];

Because a JSON Object must be of type NSArray or a NSDictionary while you are passing a NSString.
From the docs:
An object that may be converted to JSON must have the following
properties:
The top level object is an NSArray or NSDictionary.
All objects are instances of NSString, NSNumber, NSArray, NSDictionary, or NSNull.
All dictionary keys are instances of NSString.
Numbers are not NaN or infinity.
UPDATE
You probably want to do this:
NSData *jsonData = [JSON dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&err];

Related

How to parse json string into key value pairs?

Unable to parse json string
I have got the following hard coded json. I tried converting it to dictionary and parse it but Im unable to do so.
NSString *hcResponse = #"{\"status\":1,\"value\":\"Successfully Login\"}";
How to parse such a json into key value pairs?
Finally, I've figured it by myself
//convert the string to nsdata
NSData *jsonData = [hcResponse dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
//convert the data to json dictionary
NSDictionary *jsonDic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error:nil];

Getting element from NSString

my app get data from a php web service and return a NSString
["first name","last name","adress","test#test","000-000-0000","password","code","0"]
How can i get the second element ?
This is a JSON formatted string which you are getting from your web service.
You must be getting bytes from server. Just replace your variable which have bytes stored with my variable "response data".
Code:
NSError* error;
NSArray* myResultArray = [NSJSONSerialization
JSONObjectWithData:responseData options:kNilOptions error:&error];
You will get an array in variable "myResultArray" and you can get all value by index.
Code:
NSString* first name = [myResultArray objectAtIndex:0];
What you have given here is an array and not a string. May be you could provide more details like the exact response and the code that you are trying here.
To Convert a JSON string to NSDictionary all you need to do is:
NSError *jsonError;
NSData *objectData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:objectData
options:nil
error:&jsonError];
And to NSArray :
NSArray *array = [NSJSONSerialization JSONObjectWithData:objectData options:nil error:&jsonError];
NSString *secondElement = array[1];
That web service doesn't return an NSString. It runs data in some format defined by the service, and you convert it to an NSString. Find out what the format actually is, then convert it appropriately, for example using NSJSONSerialization.
The example string your showed here seems wired. This looks more like a array than string. If this is a NSArray then you can do it like this:
NSArray *data = #[#"first name",#"last name", #"adress", #"test#test", #"000-000-0000", #"password", #"code", #"0"];
NSLog (#"Second component = %#", data[1]);
However, if you anticipate this as NSString then this is how you would handle this:
NSString *test = #"[\"first name\",\"last name\",\"adress\",\"test#test\",\"000-000-0000\",\"password\",\"code\",\"0\"]";
NSLog (#"Second component = %#", [test componentsSeparatedByString:#","][1]);

What is the advantage or benefit of using NSDictionary while parsing JSON?

I know we usually use NSDictionary or NSArray while we do serialization but I wonder are there any advantages if we prefer NSDictionary?
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
This is not a matter of preference. The JSONObjectWithData: method returns an object of type id.
A Foundation object from the JSON data in data, or nil if an error
occurs.
So it is not that you can choose whether you want an NSArray or NSDictionary. In fact, you should always make a check to make sure that the returned object is of a type you expect.
Your code should look like:
NSError* error;
id JSONObject = [NSJSONSerialization JSONObjectWithData:responseData
options:kNilOptions
error:&error];
if ([JSONObject isKindOfClass:[NSDictionary class]])
{
NSDictionary *JSONDictionary = (NSDictionary *)JSONObject;
// Do your stuff.
}
Otherwise, you are risking a crash when JSON returned from the endpoint you are calling is not a dictionary anymore, but an array or anything that you don't expect.

JSON error: <error: expected ']' error: 1 errors parsing expression >

I'm having trouble parsing my JSON. The JSON is:
{"privatecode":"XDhUZQ1rA2gBZwshV2NrZQRnDmVPZQhuVj7WOlNrC29SPwg6VDUGelU1DahQNlc1AWpcPVBuWmc"}
I'm using following code:
id parsedObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:&localError];
The class of parsedObject is NSDictionary, but it contains the following error:
(<invalid>) [0] = <error: expected ']'
error: 1 errors parsing expression
>
Of course I could say:
NSDictionary *parsedObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:&localError];
but this makes no difference. I just want to get the privatecode as an NSString object, so what am I doing wrong and how can I fix this?
Many thanks in advance.
EDIT: Some more code I'm using:
NSLog(#"Response: %#", [request responseString]);
id parsedObject = [NSJSONSerialization JSONObjectWithData:[request responseData] options:0 error:&localError];
request is of type ASIHTTPRequest. The output of the log is:
Response: {"privatecode":"XDhUZQ1rA2gBZwshV2NrZQRnDmVPZQhuVj7WOlNrC29SPwg6VDUGelU1DahQNlc1AWpcPVBuWmc"}
Use this:
NSDictionary *parsedObject = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&localError];
I am using this for my project without any problem. Hope this helps. :)
EDIT:
From your error it seems that it is an array (array starts with '['). But your posted JSON is Dictionary (starts with '{'). It is weird. I searched and got this. Check this:
if ([returnedFromWeb respondsToSelector:#selector(objectAtIndex:)]) { // you can replace respondsToSelector:#selector(objectAtIndex:) by isKindOfClass:[NSArray class]
//it's an array do array things.
} else {
//it's a dictionary do dictionary things.
}
This worked for me, I was getting the same error you are but my response is an array. Since it looks like you are expecting a dictionary I'll include what that might look like.
id test = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:error];
NSArray *array;
NSDictionary *dictionary;
if ([test isKindOfClass:[NSArray class]]) {
//it's an array do array things.
array = [NSArray arrayWithArray:test];
} else {
//it's a dictionary do dictionary things.
dictionary = [NSDictionary dictionaryWithDictionary:test];
}
At this point you should be able to access the contents of the array or dictionary.
Simplified:
NSArray *array = [NSArray arrayWithArray:[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:error]];
OR
NSDictionary *dictionary = [NSDictionary dictionaryWithDictionary:[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:error]];

iOS - Nested NSDictionaries to NSArray

My Json response is
[{"id":"1", "x":"1", "y":"2"},{"id":2, "x":"2", "y":"4"}]
And I did
NSString *response = [request responseString];
SBJSON *parser = [[SBJSON alloc] init];
NSArray *jsonObject = [parser objectWithString:response error:nil];
At this point I believe that jsonObject is a array that has two NSDictionary..
How can I make jsonObject that has two NSArray instead of NSDictionary?
What is the best way to do so? I think that I need to convert nested NSDictionary to NSArray?
I would use the NSJSONSerialization class now in the Foundation framework.
With the JSONObjectWithData method, it will return the type of container you want the data stored in at the top level. For example:
NSError *e;
NSArray *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:&e];
for (NSDictionary *dict in jsonObject) {
NSLog(#"json data:\n %#", dict);
// do stuff
}
Alternately, you could return a mutable container, such as:
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&e];
Here is the Apple documentation:
NSJSONSerialization

Resources