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.
Related
So I was working on a project that required me to work with some JSON, I was running into a few issues regarding the best way of representing things. First of, this is how the JSON looks:
"phoneList": [
{
"phoneReason": "End of Contract",
"phoneType": [
{
"id": 5,
"phoneType": "Android Smartphone"
}
]
}
]
I want to know the most appropriate way of representing this.
For example, I do know that that my phoneReason will just be a simple NSString while my phoneType is actually a NSArray. However,I wasn't sure how to represent a)the id, I know this is an integer, but should this be an NSInteger or an NSNumber and b)could someone point me in the direction of some sample code where I can understand how to model a dictionary object containing an integer and a string and also where I can understand how to model an array of dictionaries.
My other question is also similar in that say I'm actually posting something, how do I model this, specifically say for like dictionary type (JSON Curly Brace)objects that contain a number/integer and a string.
For example, this is the JSON I'm trying to model and then do something like this:
"phoneReason": "Upgrade",
"phoneInfo": {
"id": "2"
},
//And then I want to pass ID
-(void) createOurRequest:(NSNumber *)id {
NSDictionary *myDictionary = #{
#"phoneReason" : [NSString stringWithFormat:#"%i", s elf.dat.reason],
//How do I then represent the phoneInfo element exactly?
};
Sorry, for the clumsy question, would really appreciate any guidance on modeling JSON in iOS or just generally.
I'm assuming you're asking questions a) and b), and also how to model a JSON.
a) The unfortunate thing with Obj-C is that all collection elements have to be objects. Integers are value types, so they will need to be converted to NSNumbers to work. However, if you're parsing a JSON string, the builtin JSON parser does it for you. I'll describe it below.
b) The model is based on the JSON. You describe the object collection and the parser will determine the model for you. In your example, you would have a NSDictionary<NSString *: NSArray<NSDictionary<NSString *: id>*>*>. The innermost element has value of id because you can either have an NSString ("End of Contract") or an NSArray ("phoneType": [ { "id": 5, "phoneType": "Android Smartphone" } ])
Of course, the model is defined by your JSON, so if you run it through a parser, you get a structured object. You can access each element based on your model (object[#"phoneList"][#"phoneReason"]).
The class method to use is:
+ (id)JSONObjectWithData:(NSData *)data
options:(NSJSONReadingOptions)opt
error:(NSError **)error
Where you pass it a NSData representation of your string, options (or 0), and a NSError pointer (error*). You get back a parsed JSON with the proper structure you defined.
NSDictionary *parsedJSONObject = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:NULL
I have no options to use and I know there will be no error, so I pass nothing for those parameters. The resulting object will be in whatever structure your JSON is.
Using the objects and the json layout you provided in your first example, this is how I would go about creating the dictionaries and arrays to get the json in the format you specified. Hopefully this helps make it a little clearer for you.
// example constructor method
-(void) jsonStringWithPhoneReason:(NSString*)reason phoneId:(NSInteger)phoneId phoneType:(NSString*)phoneType
{
// create device detail dictionary
NSDictionary *deviceOneDetail = #{
#"id" : #(phoneId), // <- set phone id as NSNumber
#"phoneType" : phoneType // <- set your string phone type
};
// create device dictionary
NSDictionary *deviceOne = #{
#"phoneReason" : reason, // <- set your phone reason string
#"phoneType" : #[deviceOneDetail] // <- set your phone type dictionary within an array
};
// create phone list dictionary with any device dictionaries you want to add
NSDictionary *phoneListDict = #{
#"phoneList" : #[
deviceOne, // <- add your device to the phone list array of dictionaries
// deviceTwo...
]
};
NSString *jsonString = [self convertToJsonString:phoneListDict]; // <- convert the dictionary into a json string and use however you wish
// your json string should now look like this assuming you pass 'End of Contract', 5 & 'Android Smartphone' as arguments to this method
// {"phoneList":[{"phoneReason":"End of Contract","phoneType":[{"id":5,"phoneType":"Android Smartphone"}]}]}
}
-(NSString*) convertToJsonString:(NSDictionary*)dictionary
{
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary
options:0 // Pass 0 if you don't care about the readability of the generated string
error:&error];
if (error)
{
NSString *errorDesc = [NSString stringWithFormat:#"Error creating json data from dictionary: %#", error.localizedDescription];
NSLog(#"ERROR: %#", errorDesc);
jsonData = nil;
return nil;
}
NSString *returnString = nil;
if(jsonData != nil)
{
returnString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
return returnString;
}
I am working on an App and I use my JSON RESTful API. Therefor I parse JSON like in the following example:
NSData * apiReturn;
NSError *myError = nil;
NSDictionary *res = [NSJSONSerialization JSONObjectWithData:apiReturn options:NSJSONReadingMutableLeaves error:&myError];
If I now pass the following JSON encoded String via the API to the App:
{"da": {"name":"dienstlicher Anlass", "duty":true, "type":"dropdown",
"values":{"gt":{"name":"Gesprächstermin", "recurring":true,
"values":{"fa":{"name":"Firma", "duty":true, "type":"text",
"multiline":false}, "ar":{"name":"Anrede", "duty":true, "single":true,
"type":"checkbox", "values":{"fr":{"name":"Frau"},
"hr":{"name":"Herr"}}}, "nm":{"name":"Gesprächspartner", "duty":true,
"type":"text", "multiline":false}, "bm":{"name":"Bemerkung",
"duty":false, "type":"text", "multiline":true}}}}
},"bm":{"name":"Bemerkung", "values":[],
"type":"text"},"bm2":{"name":"Bemerkung", "values":[], "type":"text"}}
(You can parse this a bit prettier here: http://json.parser.online.fr)
The NSDictionary should contain the following Keys: "da", "bm", "bm2" - Sorted this way, because this is the sorting of the JSON String!
But what Objective-C does, is this:
Why does Objective-C sort the elements, and why so wrong?
I hope you can help! :)
An NSDictionary is not guaranteed to store the keys in any given order.
I have got entities in core data with one to many relationship. How can I convert data in my entities to json string and populate core data entities with json string once it is created?
Any help would be greatly appreciated...
for core data to json:
fetch the data from your coredata according to your requirements, & then converts it into json.
visit this link to core data to json
also see this one
for json to core data
1)convert JSON to native Cocoa data types (NSDictionary and NSArray)
2)convert NS* into Core Data object
that means you can retrieve your json data into any array or any object & then insert that object or data into core data.
get data from json like this
NSMutableArray *json = (NSMutableArray* )[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&err];
Book.name = [[[json valueForKey:#"boxesDetail"] objectAtIndex:i] valueForKey:#"name"];
Book.ID = [NSNumber numberWithInt:[[[[json valueForKey:#"boxesDetail"] objectAtIndex:i] valueForKey:#"number"] intValue]];
now insert this Book data into core data
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
Im getting a response from twitter in the form of a string,
What I need is to send the parts where is a comment to an array,
here an example of the string
[{"geo":null,"coordinates":null,"retweeted":false,...
"text":"#KristinaKlp saluditos y besos d colores!"},{"geo":null,"coordinates...
so what I really need are the posts after "text":" =
#KristinaKlp saluditos y besos d colores!
So, how can I take the string and parse it so I get all the messages in an array hopefully?
Thanks a lot!
I haven't done JSON parsing myself in an iOS App, but you should be able to use a library like the json-framework. This library will allow you to easily parse JSON and generate json from dictionaries / arrays (that's really all JSON is composed of).
SBJson docs:
JSON is mapped to Objective-C types in the following way:
null -> NSNull
string -> NSString
array -> NSMutableArray
object -> NSMutableDictionary
true -> NSNumber's -numberWithBool:YES
false -> NSNumber's -numberWithBool:NO
integer up to 19 digits -> NSNumber's -numberWithLongLong:
all other numbers -> NSDecimalNumber
Since Objective-C doesn't have a dedicated class for boolean values,
these turns into NSNumber instances. However, since these are
initialised with the -initWithBool: method they round-trip back to JSON
properly. In other words, they won't silently suddenly become 0 or 1;
they'll be represented as 'true' and 'false' again.
As an optimisation integers up to 19 digits in length (the max length
for signed long long integers) turn into NSNumber instances, while
complex ones turn into NSDecimalNumber instances. We can thus avoid any
loss of precision as JSON allows ridiculously large numbers.
#page objc2json Objective-C to JSON
Objective-C types are mapped to JSON types in the following way:
NSNull -> null
NSString -> string
NSArray -> array
NSDictionary -> object
NSNumber's -initWithBool:YES -> true
NSNumber's -initWithBool:NO -> false
NSNumber -> number
#note In JSON the keys of an object must be strings. NSDictionary
keys need not be, but attempting to convert an NSDictionary with
non-string keys into JSON will throw an exception.
NSNumber instances created with the -numberWithBool: method are
converted into the JSON boolean "true" and "false" values, and vice
versa. Any other NSNumber instances are converted to a JSON number the
way you would expect.
Tutorials
Are there any tutorials? Yes! These are all tutorials provided by
third-party people:
JSON Framework for iPhone - a Flickr tutorial in three parts by John
Muchow. JSON Over HTTP On The iPhone - by Dan Grigsby. AS3 to Cocoa touch: JSON by Andy Jacobs.
There are other libraries you can check out as well like TouchJSON, JSONKit, Yet Another JSON Library
NSJSONSerialization does the job of converting your JSON data into usable data structures as NSDictionary or NSArray very well. I recommend it, even more because it is part of the Cocoa public interface and it is maintained by Apple.
However, if you want to map the content of your JSON to your Objective-C objects, you will have to map each attribute from the NSDictionary/NSArray to your object property. This might be a bit painful if your objects have many attributes.
In order to automatise the process, I recommend you to use the Motis category (personal project) on NSObject to accomplish it, thus it is very lightweight and flexible. You can read how to use it in this post. But just to show you, you just need to define a dictionary with the mapping of your JSON object attributes to your Objective-C object properties names in your NSObject subclasses:
- (NSDictionary*)mjz_motisMapping
{
return #{#"json_attribute_key_1" : #"class_property_name_1",
#"json_attribute_key_2" : #"class_property_name_2",
...
#"json_attribute_key_N" : #"class_property_name_N",
};
}
and then perform the parsing by doing:
- (void)parseTest
{
NSData *data = jsonData; // <-- YOUR JSON data
// Converting JSON data into NSArray (your data sample is an array)
NSError *error = nil;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
if (error)
return; // <--- If error abort.
// Iterating over raw objects and creating model instances
NSMutableArray *parsedObjects = [NSMutableArray array];
for (NSDictionary *rawObject in jsonArray)
{
// Creating an instance of your class
MyClass instance = [[MyClass alloc] init];
// Parsing and setting the values of the JSON object
[instance mjz_setValuesForKeysWithDictionary:rawObject];
[parsedObjects addObject:instance];
}
// "parseObjects" is an array with your parsed JSON.
// Do whatever you want with it here.
}
The setting of the properties from the dictionary is done via KeyValueCoding (KVC) and you can validate each attribute before setting it via KVC validation.
I recently had to do this. After looking at the various options out there, I threw JSONKit into my app (I found it on a JSON discussion on StackOverflow). Why?
A) It is VERY VERY simple. I mean, all it has is the basic parsing/emitting functions, what more do you need?
B) It is VERY VERY fast. No overhead - just get the job done.
I should note, I had never done JSON before - only heard of the term and didn't even know how to spell it. I went from nothing, to a working app, in about 1 hour. You just add one class to your app (the .h, .m), instantiate it, and call the parser to a dictionary object. Voila. If it contains an array, you just get the objectForKey, cast it as an NSArray. It's really hard to get simpler than that, and very fast.
For a good comparison of the speed of the different libraries for JSON parsing on iOS, take a look at The Ultimate Showdown.
-(IBAction)btn_parse_webserivce_click:(id)sender
{
// Take Webservice URL in string.
NSString *Webservice_url = self.txt_webservice_url.text;
NSLog(#"URL %#",Webservice_url);
// Create NSURL from string.
NSURL *Final_Url = [NSURL URLWithString:Webservice_url];
// Get NSData from Final_Url
NSData* data = [NSData dataWithContentsOfURL:
Final_Url];
//parse out the json data
NSError* error;
// Use NSJSONSerialization class method. which converts NSData to Foundation object.
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:data
options:kNilOptions
error:&error];
// Create Array
NSArray* Response_array = [json objectForKey:#"loans"];
NSLog(#"Array: %#", Response_array);
// Set Response_array to textview.
self.txt_webservice_response.text = [NSString stringWithFormat:#"%#"
,Response_array];
}
How about NSJSONSerialization? I've been using it to parse JSON
http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSJSONSerialization_Class/Reference/Reference.html