convert NSMutableDictionary to JSON and string - objective-c

I want to add a json data to HTTPBody request for an iOS app.
I am using objective c.
So I decided to use NSMutableDictionary to convert it to JSON
#property NSMutableDictionary* project;
Parameters:
project (required): a hash of the project attributes, including:
name (required): the project name
identifier (required): the project identifier
description
This is the JSON format when adding data as a raw:
If I want the JSON to look like this, do I have to create NSMutableDictionary object and have another NSMutableDictionary object inside it with the key name #"project"?
{
"project": {
"name": "",
"identifier": "example",
"description": "",
}
}
I tried to have only one NSMutableDictionary
Here is my code:
[self.project setObject:self.projectName.text forKey:#"name"];
[self.project setObject:self.projectDescription.text forKey:#"description"];
[self.project setObject:self.projectIdentifier.text forKey:#"identifier"];
Here is how to convert it to JSON:
NSData *data = [NSJSONSerialization dataWithJSONObject:project options:NSJSONWritingPrettyPrinted error:nil];
NSString* jsonString = [[NSString alloc]initWithData: data
encoding: NSUTF8StringEncoding ];
NSData* anotherdataobj = jsonString;
[request setHTTPBody:anotherdataobj];
I convert it to NSData again because HTTPBody accept NSData for the parameter.
To be clear:
1- do i have to create NSMutableDictionary for project and add NSMutableDictionary projectdetails as a value for for its key #"project"
2- Do I have to convert the string into NSData again to pass it for the HTTPBody?
Correct me if i'm wrong here?

You will definitely need another dictionary inside the first one. Whether you use a mutable version or a literal is up to you.
Note: you probably want to use the newer and much more readable Objective-C syntax.
Option 1:
NSMutableDictionary *object = [NSMutableDictionary dictionary];
NSMutableDictionary *project = [NSMutableDictionary dictionary];
project[#"name"] = whatever;
project[#"identifier"] = whateverElse;
project[#"description"] = stillSomethingElse;
object[#"project"] = project;
Option 2:
NSDictionary *object =
#{
#"project":
#{
#"name": whatever,
#"identifier": whateverElse,
#"description": stillSomethingElse,
}
};
NSJSONSerialization dataWithJSONObject:options:error: already returns an NSData object? Why would you need to convert it again? Also, you certainly don't want to cast an NSData object to an NSString, they're two completely different objects.

Related

Converting a JSON file to NSMutableDictionary in Objective C?

I have a json file that looks like this:
{
"data":
{
"level": [
{
//bunch of stuff
}
]
}
}
Now I want to convert that into a array of levels that I can access. If I take away the {"data: part, then I can use this:
NSData *allLevelsData = [[NSData alloc] initWithContentsOfFile:fileLoc];
NSError *error = nil;
NSMutableDictionary *allLevels = [NSJSONSerialization JSONObjectWithData:allLevelsData options:kNilOptions error:&error];
if(!error){
NSMutableArray *level = allLevels[#"level"];
for (NSMutableDictionary *aLevel in level){
//do stuff with the level...
But I have to have the {"data: as part of the file, and I can't figure out how to get a NSData object out of the existing NSData object. Any ideas?
Don't you need to pull the level NSArray out of the data NSDictionary first?
NSData *allLevelsData = [[NSData alloc] initWithContentsOfFile:fileLoc];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:allLevelsData options:kNilOptions error:&error];
if(!error){
NSArray *levels = dataDictionary[#"data"][#"level"];
for (NSDictionary *aLevel in levels){
//do stuff with the level...
You won't get mutable objects back by default and declaring the variables as mutable doesn't make them so. Take a mutableCopy of the result instead (assuming you really do need mutability).
Why are you trying to prune ahead of time? If you decode the original JSON, you'll be able to extract the level array from the data dict in the decoded dict.
It's not clear what else you're trying to accomplish or why you are going the path you ask about. Note, this doesn't necessarily mean your path is wrong, just that without a clearer indication of what goal you're really trying to accomplish or what you've actually tried (and errored/failed, along with how it failed), you're likely only to get vague/general answers like this.

How to serialize NSManagedObject to JSON in restkit 0.20?

How to serialize NSManagedObject to JSON in restkit 0.20 using inverse mapping?
Right now I don't need to post anything anywhere.
I would like manually create object MyObjectManaged.
Set some attributes for example:
id,
name,
age
Map them with existing mapping my mapping to JSON attributes:
userid,
first_name,
age
create and print JSON.
Is it possible? When yes, how?
Thank you in advance for your answer.
I've recently been trying to do the same thing :) I wanted to keep the mappings so that eventually I can hook up to a server, but also reuse them for serializing objects out to a file.
I did this using the inverseMapping and running it through an RKMappingOperation.
First set up your mappings from JSON -> Core Data Object
RKEntityMapping mapping = [RKEntityMapping mappingForEntityForName:#"MyManagedObject" inManagedObjectStore:rkManagedObjectStore];
[self.nodeMapping addAttributeMappingsFromDictionary:#{
#"userid": #"id",
#"first_name": #"name",
#"age": #"age"
}];
Then use the inverse mapping to map your object instance (e.g. "myObject") to a dictionary:
NSMutableDictionary *jsonDict = [NSMutableDictionary dictionary];
RKObjectMappingOperationDataSource *dataSource = [RKObjectMappingOperationDataSource new];
RKMappingOperation *operation = [[RKMappingOperation alloc] initWithSourceObject:myObject
destinationObject:jsonDict
mapping:[mapping inverseMapping]];
operation.dataSource = dataSource;
NSError *error = nil;
[operation performMapping:&error];
Assuming there's no error, you can then serialize the dictionary:
NSData *data = [RKMIMETypeSerialization dataFromObject:jsonDict
MIMEType:RKMIMETypeJSON
error:&error];
Not sure what you wanted to do with it from there, but if you wanted to print it to a string you could do:
NSString *jsonString = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding]
Hope that helps
John Martin answer seems to work but I got the problem that NSManagedObject instances with a NSNumber property that is set with
[NSNumber numberWithBool:boolvalue]
serializes a json as value 1/0 instead of true/false.
Our backend could not handle numbers as booleans.
I solved this with using the RestKit built in class: RKObjectParameterization
Using the follow method my NSManagedObjects were properly serialized when there was an NSNumber property that was set as a bool.
+ (NSString *)getJsonObjectWithDescriptor:(RKRequestDescriptor *)requestDescriptor objectToParse:(id)objectToParse {
NSError *error = nil;
NSDictionary *jsonDict = [RKObjectParameterization parametersWithObject:objectToParse requestDescriptor:requestDescriptor error:&error];
NSData *data = [RKMIMETypeSerialization dataFromObject:jsonDict
MIMEType:RKMIMETypeJSON
error:&error];
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
You can head over to the RestKit wiki and have a look in the object mapping. In the paragraph "Object Parameterization & Serialization" you'll find the information about the serialization and inverse mapping.

How to convert json string to nsdictionary on json parser framework on objective c

I am trying to convert raw json string to NSDictionary. but on NSDictionary i got different order of objects as on json string but i need exactly same order in NSDictionary as on json string. following is code i have used to convert json string
SBJSON *objJson = [[SBJSON alloc] init];
NSError *error = nil;
NSDictionary *dictResults = [objJson objectWithString:jsonString error:&error];
From NSDictionary's class reference:
The order of the keys is not defined.
So, basically you can't do this when using a standard NSDictionary.
However, this may be a good reason for subclassing NSDictionary itself. See this question about the details.
NSDictionary is an associative array and does not preserve order of it's elements. If you know all your keys, then you can create some array, that holds all keys in correct order (you can also pass it with your JSON as an additional parameter). Example:
NSArray* ordered_keys = [NSArray arrayWithObjects: #"key1", #"key2", #"key3", .., nil];
for(NSString* key is ordered_keys) {
NSLog(#"%#", [json_dict valueForKey: key]);
}
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData //1
options:kNilOptions
error:&error];
NSArray* latestLoans = [json objectForKey:#"loans"]; //2
NSLog(#"loans: %#", latestLoans); //3
Source: Follow this link http://www.raywenderlich.com/5492/working-with-json-in-ios-5
Good tutorial but works only on iOS5

Best approaches on "filling" a json file , iOS?

I am working on an application and i need to send some data to my server. The data is in json format and more specific the json file looks like this :
{
"eventData": {
"eventDate": "Jun 13, 2012 12:00:00 AM",
"eventLocation": {
"latitude": 43.93838383,
"longitude": -3.46
},
"text": "hjhj",
"imageData": "raw data",
"imageFormat": "JPEG",
"expirationTime": 1339538400000
},
"type": "ELDIARIOMONTANES",
"title": "accIDENTE"
}
So i have tried to hardcode the data in my json file and everything works ok. Now what i am trying to do is to fill my json file , using variables so everything can work automatcally when data changes. What would a good approach be for that?? Some sample code would be highly appreciated as i am very new to obj-c. Thanks for ur time! :D
EDIT
Ok so an NSDictionary seems a nice way to go.
But how can i create a dictionary to look like the json format?? I ve only used dictionaries like this :
NSArray *keys = [NSArray arrayWithObjects:#"eventDate", #"eventLocation", #"latitude" nil];
NSArray *objects = [NSArray arrayWithObjects:#"object1", #"object2", #"object3", nil];
dictionary = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
For the langitude and longitude for example it is a pair of key and value but for the rest??
All you need is a NSDictionary containing your keys and values. Since iOS5, you can proceed with the following code
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:myDictionary
options:NSJSONWritingPrettyPrinted
error:&error];
if (!jsonData) {
NSLog(#"Got an error: %#", error);
} else {
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
// ...
}
I have used this library . It is very simple and useful. And for tutorial check this site.

Can I minimize the number of objects used in this SBjson code?

The response I receive from the server is formatted as such:
{
"Data":{
"Key": "Value"
...
},
"Key": "Value"
...
}
However, I am only interested in the elements under "Data".
Here is the code I'm currently using:
SBJsonParser *parser = [SBJsonParser new];
NSString *responseString = [request responseString];
NSDictionary *responseData = [parser objectWithString:responseString];
NSString *infoString = [responseData objectForKey:#"Data"];
NSDictionary *infoData = [parser objectWithString:infoString];
Is there a way to perform the same thing without explicitly declaring 5 objects? Just looking for some sense of short-hand that I should be using.
Your last two lines are wrong - "Data" is actually an NSDictionary, so you don't need to double parse it.
Also, most objective-C programmers would nest calls where they know that the returns are safe - by which I mean don't need additional checking. For instance, this would see a more natural implementation to me:
NSDictionary *responseDictionary = [[request responseString] JSONValue];
NSDictionary *infoData = [responseDictionary objectForKey:#"Data"];
Note that I am using the convenience method JSONValue from the category on NSObject that comes with SBJSON.