Creating JSON file using NSDictionary with an array - ios

I am attempting to create json data to send to a server via an HTTP POST request. The server will only accept a specific format of JSON, otherwise it will return an error. I can successfully create and upload the JSON file to the server, however I am getting the following error because I have not formatted my JSON incorrectly:
JSON Error Message: {
code = "-2";
message = "Validation error: {\"message\":{\"to\":[\"Please enter an array\"]}}";
name = ValidationError;
status = error;
}
As you can see, the server needs a complex JSON format with an Array of Values and Keys but I'm not sure how to do that. Below is my current code to create the JSON data:
//Create Array With TO Values
NSDictionary *toField = #{#"email" : emailField.text};
//Create Dictionary Values
NSDictionary *messageContent = #{#"subject" : #"APPNAME Registration Complete", #"from_email" : #"email#domain.com", #"to" : toField};
NSDictionary *mandrillValues = #{#"key" : #"APPKEY",
#"redirect_url" : #"PRIVATE-URL",
#"template_name" : #"app-registration",
#"template_content" : [NSNull null],
#"message" : messageContent
};
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:mandrillValues options:NSJSONWritingPrettyPrinted error:nil];
According to the server, I need an array with keys and values, similar to a nsdictionary. When I use an NSArray, though, I can't add values / keys. Any ideas on how I should go about doing this? Below is an example of the JSON format that the server will accept, am I doing everything right to follow this format? If not, what do I need to change to match the format?
{
"key": "example key",
"template_name": "example template_name",
"template_content": [
{
"name": "example name",
"content": "example content"
}
],
"message": {
"text": "example text",
"subject": "example subject",
"from_email": "message.from_email#example.com",
"from_name": "example from_name",
"to": [
{
"email": "example email",
"name": "example name"
}
],
}}

Looks like the "to" field expects an array. Unless the variable toField is an NSArray that contains dictionaries with keys and values as described, you're going to get a JSON that's not exactly like the one you want.
I would suggest outputting the description of the outgoing JSON to see exactly where there are differences.
Update
I saw the addition to your question -
NSDictionary *toField = #{#"email" : emailField.text};
Does not create an array. Try:
NSArray *toField = #[#{#"email" : emailField.text}];

Related

How to create a NSDictionary with blank key/ without key for an object

I want to create a JSON string from a NSDictionary.The complete JSON to create is given below.
{
"source":"point a ",
"destination":"point b ",
"boardingPoint":{
"id":"2222",
"location":"Some location"
},
"customerName":"test",
"customerLastName":"testing",
"customerEmail":"test#gmail.com",
"blockSeatPaxDetails":[
{
"age":"20",
"name":"test123",
"sex":"M",
"title":"Mr",
"email":"testing#gmail.com"
}
],
"inventory":0
}
Now I am stuck at creating dictionary for the first part of this JSON ie
{
"source": "point a ",
"destination": "point b ",
"boardingPoint": {
"id": "2222",
"location": "Some location",
},
Here the boardingPoint is a dictionary which is added to one dictionary.And then along with rest of the keys I make a final dictionary.So when I create the final dictionary, with objectsAndKeys I have no key to set for the first part which is shown below.If I set blank like this #" " the JSON string shows " " as key.And ofcourse I cannot use nil.How to do it then?
This is how it apppears if I insert blank as key for the first part
{
"" : {
"source" : "point a",
"boardingPoint" : {
"id" : "2222",
"location" : "Some location",
},
"destination" : "point b"
},
This is how I create the dictionaries
NSDictionary *boardingPoint = [NSDictionary dictionaryWithObjectsAndKeys:boardingPointID,#"id", boardingLocation,#"location",nil];
NSDictionary *firstDictionary = [NSDictionary dictionaryWithObjectsAndKeys:source,#"source",dest,#"destination",nil];
NSDictionary *mainDictionary = [NSDictionary dictionaryWithObjectsAndKeys:firstDictionary, #" ",customerName,#"customerName",customerLastName,#"customerLastName",customerEmail,#"customerEmail",blockSeatPaxDetails,#"blockSeatPaxDetails",inventory,#"inventory",nil];
and then ofcourse
NSData *finalData = [NSJSONSerialization dataWithJSONObject:mainDictionary options:NSJSONWritingPrettyPrinted error:nil];
The first part of your JSON, properly indented, is:
{
"source":"point a ",
"destination":"point b ",
"boardingPoint":{
"id":"2222",
"location":"Some location",
},
"customerName":"test",
"customerLastName":"testing",
"customerEmail":"test#gmail.com",
"blockSeatPaxDetails":[
{
"age":"20",
"name":"test123",
"sex":"M",
"title":"Mr",
"email":"testing#gmail.com",
},
(You've apparently elided something toward the end so I can't slow the last few lines.)
There is no "missing key" or anything of the sort. If you feed your (unelided) JSON through NSJSONSerialization it will produce the correct "tree" of dictionaries and arrays.

Converting NSData (Json data) to nsarray : iOS

I am getting some data from WebService (which is a json data)
Exact input sent by Webservice is:
[
{
"id": "C-62",
"title": "testing testing",
"type": "image",
"thumb": "",
"LinkId": "ABC",
"fileSize":1074,
"level":0,
},
{
"id": "C-63",
"title": "testing ab testing",
"type": "audio",
"thumb": "",
"LinkId": "ABCD",
"fileSize":1074,
"level":1,
}
]
As I can see in input data that only fileSize is a integer type Key-Value pair
remaining all are in string format.
When I convert that NSData onto NSArray using following code
NSArray *dataArray = nil;
dataArray = [NSJSONSerialization JSONObjectWithData:data
options:0
error:nil];
I get "dataArray" like this
{
"id": "C-62",
"title": "testing testing",
"type": image,
"thumb": "",
"LinkId": "ABC",
"fileSize":1074,
"level":0,
},
{
"id": "C-63",
"title": "testing ab testing",
"type": audio,
"thumb": "",
"LinkId": "ABCD",
"fileSize":1074,
"level":1,
}
The "type" Key-Value pair changes to "int" .All other key-value pairs are in same state.
Please help me in order to convert the input data into the same format as sent by web service.
I am using iOS 7.
You just got yourself confused. You confuse NSLog output with what is really stored. You are also not saying the truth when you claim that only the "fileSize" field contains numbers, because clearly the "level" field does as well.
NSLog only shows strings with quotes when necessary. A string "10" would be displayed as 10 without the quotes. You can really rely on NSJSONSerializer not doing anything behind your back.
NSJSONSerialization will convert scalar numbers to NSNumbers. That's the only way these can participate in collections (arrays and dictionaries). To convert to int, access the NSNumber and convert it as follows...
NSArray *dataArray = // the de-serialized json
NSDictionary *dictionary = dataArray[0]; // the first dictionary
NSNumber *number = dictionary[#"fileSize"];
// turn an NSNumber representing an integer to a plain int
int fileSizeInt = [number intValue];
But don't try to reinsert that int back into the dictionary.
The one tricky thing about JSON on iOS is figuring out the data type of an arbitrary NSNumber. I chronicled my difficulties in this question.
A large number might be floating-point or integer, and if you attempt to extract one when you really have the other you lose significant digits. And, obviously (in retrospect), if you extract a too-large value into an int you will lose high-order bits and get totally wrong values.
(This isn't quite so difficult if you know in advance that certain values are of certain types. Then it's just a matter of using the proper "verb" to extract the expected type of value.)

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

Using a .json Database I Created

I am looking to use a .json file as a database to pull data from. I want to convert each index of the json file into an array which can be used for a tableview and segue.
[
{
"email address": "test#gmail.org",
"first name": "First",
"last name": "Last"
},
{
"email address": "test2#gmail.org",
"first name": "First2",
"last name": "Last2"
}
]
From there, I want to be able to convert each index into:
NSArray*testArray = #[#"test#gmail.org",#"First",#"Last"];
How would I go about doing this?
Use NSJSONSerialization to put your JSON into a dictionary.
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
When you have done that, you can access your data by key, which keeps your code much cleaner than using hard coded array indexes.

Need to prefix JSON document being generated from NSMutableDictionary in iOS

I am able to successfully generate a JSON document by iterating through a NSMutableDictionary. This NSMutableDictionary in turn, contains two values that are also NSMutableDictionary's, the keys of which are reports, and results respectively.
The code that constructs the JSON document is as follows:
NSMutableDictionary *jsonDoc = [NSMutableDictionary dictionary];
[jsonDoc setObject:results forKey:#"results"];
[jsonDoc setObject:reports forKey:#"reports"];
NSError *ierror = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonDoc options:NSJSONWritingPrettyPrinted error:&ierror];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"JSON Output: %#", jsonString);
and my JSON output looks like this:
JSON Output: {
"results" : [
{
"date" : "2012-12-25T16:58:25",
"name" : "Test 1",
"result" : "Fail"
},
{
"date" : "2012-12-25T16:58:33",
"name" : "Test 2",
"result" : "Pass"
},
{
"date" : "2012-12-25T16:58:38",
"name" : "Test 3",
"result" : "Pass"
},
{
"date" : "2012-12-25T16:58:45",
"name" : "Test 4",
"result" : "Fail"
}
],
"reports" : [
]
}
I am very happy with the output I am getting. However, what I would like to do now is to prefix the data I am outputting with additional details that would go after the JSON Output: { but before "results". The additional details are simply NSString values like "Name:", "Address", "City", "Province", "Postal Code", etc. How would I do this given the code structure that I have presently? The catch is that I would like these details to be part of the original JSON object when I am initially building the JSON object, and not simply when I am outputting to the console.
Just call setObject:forKey: for each of the key/value pairs you want to add to the jsonDoc dictionary. It doesn't matter whether you put them above or below the two calls you have in your question since dictionaries are unordered.

Resources