JSON parse returns NSDicationary with empty values - ios

I'm trying to transform a very simple JSON in to a NSDicationary to then populate my CoreData model with the retrieved data, the problem is after I get my json from the server and try to parse it to a NSDicationary my dictionary just show I have 811 values inside but they all are empry values.
I have printed my json (NSData) and all the content is there and my error var is null after this point.
This is the piece of code I use to do the parse:
[NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves error:&error]
And here is an example of my JSON:
[
{
"product": "A",
"name": "B"
},
{
"product": "B",
"name": "A"
}
]
If I print the data using the code below, the result is exactly the same I get from my server:
[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]
After clicking in the "I" (information) icon I got that:
Execution was interrupted, reason: Attempted to dereference an invalid
ObjC Object or send it an unrecognized selector. The process has been
returned to the state before expression evaluation.
But can't understand why...
I have already searched for this on stackoverflow and I didn't find any solution to my problem, maybe I'm searching with the wrongs terms.

You say you are parsing your JSON into an NSDictionary but the top-level data structure of your JSON is an array. Parse your JSON into an NSArray; each element of this array will be an NSDictionary.

Related

Error in JSON encode

I have a problem when encode an NSMutableArray array of custom object (Room).
My custom object is : -nameRoom (NSString) -numberRoom (NSInteger).
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:array options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
This is the error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (Room)
Thanks.
From the docs (yes, sometimes reading the documentation is helpful)
You use the NSJSONSerialization class to convert JSON to Foundation
objects and convert Foundation objects to JSON.
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.
Other rules may apply. Calling isValidJSONObject: or attempting a
conversion are the definitive ways to tell if a given object can be
converted to JSON data.
JSON does not support custom objects.
See: Introducing JSON.
In order to support a custom object you will have to break it down into a graph of standard JSON objects. In the OP's case it will simply be a dictionary containing nameRoom and numberRoom.

iOS Game Center send json in match data

I am trying to send JSON data in matchData object when a user end its turn. If I check the json before sending it is valid and looks like,
JSON:
{
"p1score" : "0",
"turn" : "0",
"pb1" : "BPS1120|2231|3422|4213|5244|6135",
"player2" : "0000177110",
"player1" : "0000177110",
"p2score" : "0",
"movements" : "MVS2242",
"pb2" : "BPS1630|2511|3522|4543|5534|6625",
"moves" : "30"
}
Prepares the data for sending,
NSData *matchData = [[NSString stringWithFormat:#"%#",realMatchData] dataUsingEncoding:NSUTF8StringEncoding];
realMatchData contains the above json string.
But if convert the matchData back to string again to check what is being sent using,
NSString *str = [[NSString alloc] initWithData:matchData encoding:NSUTF8StringEncoding];
I get back the following json string
{
"moves" : "30",
"turn" : "0",
"player2" : "G:0000177110",
"p1score" : "0",
"player1" : "G:0000177110",
"movements" : "MVS",
"p2score" : "0"
}
keys pb1 and pb2 are missing.
I event tried to pass the values of pb1 and pb2 as nested json but problem remains the same, they keys are missing when sending data.
Is the right way to share the game state or should I use some other approach to share data ?
Thanks.
This does not answer the question exactly, but it may solve the problem, and the asker asked for an example. Apple provides its own JSON serialization which produces an NSData object from JSON serializable objects like NSNumber, NSArray, NSString, NSDictionary, etc.
NSMutableArray* matchArray = [NSMutableArray array];
/*
Fill the match array with the appropriate objects to represent your game state...
You've presumably already done this in order to get that string object...
*/
NSData* matchData = [NSJSONSerialization dataWithJSONObject: matchArray
options: 0 //pretty sure all the options here are irrelevant for our purposes
error: NULL]; //pass in a pointer to an NSError if you are interested in the error
//end the turn or do whatever one does in a non-turn-based match with matchData as the data object

JSon array to core data entity

I have a cuestion about parsing a Json strings.
If i'm getting a string like:
[["AR","Argentina","flag_of_argentina","en","F","1"],
["AU","Australia","flag_of_‌​australia","en","B","4"]]
How can i save this string into an entity when normally i see Jsons that have something like this:
(
(
"Group_id": 1,
"Date" : "2014-04-08",
"Hour" : "18:00:00",
"Location":"Guayaquil, Ecuador",
"State" : A
),
...
If i have to make an array or something else to store it to the entity in core data how can i do it?
I hope my question is well made ​​and I appreciate your help. Thank you very much.
Cocoa Touch provides a built in class that helps you serialize this data. It's called NSJSONSerialization.
So, that looks to me like you have arrays within an array. First you're going to want to convert the NSString to NSData:
NSData *JSONdata = [yourJSONString dataUsingEncoding:NSUTF8StringEncoding];
Then serialize it into an array:
NSArray *JSONArray = [NSJSONSerialization JSONObjectWithData:JSONdata options:NSJSONReadingMutableContainers error:&error];
Then you can access any subarray by writing:
NSArray *countryData = [JSONArray objectAtIndex:i];
And from there you can access the data that you need.
~
As for building JSON Data, you'll need to construct an NSMutableDictionary and populate it accordingly. Once you have that, use the same class NSJSONSerialization to convert it to a JSON string.

Keeping the order of NSDictionary keys when converted to NSData with [NSJSONSerialization dataWithJSONObject:]

I have the following situation:
NSDictionary *params = #{
#"Checkout" : #{
#"conditions" : #{#"Checkout.user_id" : #1},
#"order" : #{#"Checkout.id" : #"DESC"}
},
#"PaymentState" : #[],
#"Offer" : #[]
};
This dictionary contains params for a webservice request passing a JSON string with the webservice URL. I get the JSON string using NSJSONSerialization class, like this:
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:nil];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
The problem is: jsonString "keys" is ordered differently from the original params dictionary keys order, like this:
{
"Offer":[],
"PaymentState":[],
"Checkout":{
"conditions":{"Checkout.user_id":6},
"order":{"Checkout.id":"DESC"}
}
}
That is, the "PaymentState" and "Offer" keys come first in jsonString, and i need maintain
the original order. This is very important, like this:
{
"Checkout":{
"conditions":{"Checkout.user_id":6},
"order":{"Checkout.id":"DESC"}
},
"Offer":[],
"PaymentState":[]
}
So guys, how can i do that??
I use OrderedDictionary from CocoaWithLove whenever I need to keep the order of my dictionary keys.
Basically, OrderedDictionary contains an NSMutableDictionary and an NSMutableArray for the keys inside it, to keep track of the order of the keys. It implements the required methods for subclassing NSDictionary/NSMutableDictionary and just "passes" the method call to the internal NSMutableDictionary.
According to the JSON spec a JSON object is specifically unordered. Every JSON library is going to take this into account. So even when you get around this issue for now, you're almost certainly going to run into issues later; because you're making an assumption that doesn't hold true (that the keys are ordered).
While NSDictionary and Dictionary do not maintain any specific order for their keys, starting on iOS 11 and macOS 10.13, JSONSerialization supports sorting the keys alphabetically (see Apple documentation) by specifying the sortedKeys option.
Example:
let data: [String: Any] = [
"hello": "world",
"a": 1,
"b": 2
]
let output = try JSONSerialization.data(withJSONObject: data, options: [.prettyPrinted, .sortedKeys])
let string = String(data: output, encoding: .utf8)
// {
// "a" : 1,
// "b" : 2,
// "hello" : "world"
// }

Parsing JSON response with multiple objects

I've got a question regarding parsing a JSON response within iOS5.
Currently, I'm following this guide here to help me parse the JSON response returned from a third-party mapping service.
Everything works, except that the JSON response returned by the third-party server is somewhat different from the one shown in the guide itself.
In a nutshell, the overall structure of the entire JSON response looks something like this:
{
"directions": [....],
"messages": [....],
"routes":
{
"features": [
{
"attributes": {....},
"geometry":
{
"paths": [....]
}
}
]
}
}
This is the actual JSON query URL.
By using this line of code,
NSDictionary * jsonResponse = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
I am able to sucessfully get the jsonResponse dictionary to report that it has 3 key/value pairs, but my ultimate goal is to retrieve the array stored in 'routes.features.geometry.paths'.
This is my current code block that gets the final set of array values:
NSDictionary * jsonResponse = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
NSArray * jsonArray = [jsonResponse valueForKeyPath:#"routes.features.geometry.paths"];
jsonArray = [jsonArray objectAtIndex:0];
jsonArray = [jsonArray objectAtIndex:0];
I was wondering if anyone might have a better idea of how I should go about doing this in a more elegant fashion?
Thanks a lot in advance!
You can't just use it as JSON object because it will be working as JSON (Plain String) and you need to parse it so for your problem you can do like this to directly go to paths
NSArray *arr = [[[[jsonResponse objectForKey:#"routes"] objectForKey:#"features"] objectForKey:#"geometry"] objectForKey:#"paths"];
Now you can access your paths data from "arr" array
UPDATE:
NSArray *arr = [[[[[jsonResponse objectForKey:#"routes"] objectForKey:#"features"] objectAtIndex:0] objectForKey:#"geometry"] objectForKey:#"paths"];
as features element is an Array so traverse array first then goto its elements

Resources