Parsing JSON objective c - objective-c

I'm initiating a URL connection and my script is returning the following JSON:
(
1,
{
"id" = <-ID Here->;
hash = <-Hash Here->;
},
(
),
(
) )
All the examples I've seen so far seem to have "ids" or identifiers before respective arrays/dictionaries. Despite searching around, I couldn't find a way to parse this. (i.e. I need to get the first boolean value, the id, the hash, and then the arrays as well (which are empty as of now)).
Sorry if I'm missing something-- I'm new to parsing JSON in Obj-C.Thanks for the help.

The feature I use is built in with the Cocoa libraries: the NSJSONSerialization class.
It provides methods for parsing JSON into a graph, and encoding a graph into JSON. The rules are similar to plists (i.e. basic types plus arrays and dictionaries).
If you have NSData (which you can easily get from a string), you do like this:
NSArray *yourJSONAsObjectGraph = [NSJSONSerialization JSONObjectWithData:yourNSData options:nil error:&err];
Then, with your data above, objectAtIndex:0 would be an NSNumber that you can call boolValue on, objectAtIndex:1 will be an NSDictionary that you can call objectForKey:#"id" (and #"hash"), etc.

See How to use JSON in Objective-C. If you didn't hear about it yet, have a look at SBJSON.

Related

Make Whole Request UTF-8 from NSURLSession

I am making a simple NSURLSession GET request and i am returned the right data and i am able to serialize it up to one point where the data is no longer UTF-8 so i am unable to call keys of the children.
My data looks like this:
[
{
"GeoJsonData":"{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"LineString\",\"coordinates\":[[-119.1968536376953,35.5229358991794],[-119.19696092605591,35.52019399894053],[-119.19206857681274,35.520141605030304],[-119.19204711914062,35.52003681710729],[-119.18736934661865,35.52007174643016],[-119.18730497360228,35.52213254957543],[-119.18839931488039,35.52215001378275],[-119.18842077255249,35.522813650845336],[-119.19696092605591,35.522918435143076]]}}",
"GeoJsonCenter":"{\"lat\":35.52148635814335,\"lng\":-119.1921329498291}"
},
{
"GeoJsonData":"{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[-112.42687225341795,33.49409462250672],[-112.42678642272949,33.47605511894646],[-112.42549896240234,33.47605511894646],[-112.42103576660156,33.48822503770075],[-112.41022109985352,33.49438093353938],[-112.42687225341795,33.49409462250672]]]}}",
"GeoJsonCenter":"{\"lat\":33.48521802624292,\"lng\":-112.41854667663574}"
}
]
As you can see there are alot of escape characters in there and i have 85 objects in this array i need to iterate over and once i get down to the children of these objects i am not able to call those objects.
example of my code:
NSMutableArray *geoJSONData = [[NSMutableArray alloc] init];
for (NSDictionary *item in jsonArray){
[geoJSONData addObject:[item objectForKey:#"GeoJsonData"]];
}
for (NSDictionary *item in geoJSONData) {
NSLog(#"%#", [item objectForKey:#"coordinates"]);
}
the last NSLog blows up the console because it is not able to find that key "coordinates" because it is wrapped with escaped characters and i need to get those out.
Has anyone ran into this issue and whats the best way to solve this so i can have my object working fully serialized as JSON.
any help is greatly appreciated, im just getting back into Objective-c from AngularJs and last time i worked with Objective-C i used NSUrlRequest...so things have changed.
If the data that you shown is the real representation of it then you have a small issue. The value for key GeoJsonData is not an object but a string. In other words it's an object that was serialized using JSON.stringify() and added to the parent object. Quite a strange construction, that's why I'm asking if that is the real JSON representation sent by the server.
What you'll need to do before trying to access the key coordinates is to JSON parse that string to get a valid object back so you can access it's properties as a normal NSDictionary, write now is just a string.
Just use NSJSONSerialization class to decode your GeoJsonData.

Objective C - JSON to CoreData with category relation [duplicate]

I'm a nwebie in Core Data, i have designed a navigation based application and some of the data i use are created on run time(come from a URL via JSON). I took a few tutorials an searched for almost a day but haven't still realized how to save the incoming JSON data to the Entity (or event?) in my Core Data model. I fetch the data in the DetailViewController class and i need to save this data to Core Data(I have prepared an Entity with 7 properties). Can anyone please help?(If you know a good tutorial or sample code i will be pleased)
EDIT This may be a little specific but i really have trouble with and need just a little help.
My data comes to the app from a kind of restful server(i wrote it in PHP), firstly user enters his/her login informations(which i have saved to the database on server before) and when the response data comes i will use different elements of it in differen views(for example the user_id will be used on a view and the buttonData etc on other views). My question is, how will i save JSON data into my core data model(has tree Entities for the moment). Thanks in advance
Note: I lokked arround a lot but couldn't find any answer&tutorial about an app like mine
The best way to do that would be to create entities corresponding to JSON structure. Easiest was is when each JSON object becomes an entity, and arrays become arrays of entities. Be reasonable, however, and don't introduce too much overkill for JSON subobjects that are essentially part of its superobject.
When you have created entities, you can start off with the parsing and translation. Use some JSON framework (starting from iOS5 there's one from Apple) and parse JSON string into object tree, where root item is either an NSArray or NSDictionary, and subelements will be NSArray, NSDictionary, NSNumber, NSString or NSNull.
Go over them one by one in iterational loops and assign according values to your core data entity attributes. You can make use of NSKeyValueCoding here and avoid too much manual mapping of the attribute names. If your JSON attributes are of the same name as entity attributes, you'll be able to just go over all dictionary elements and parse them into attributes of the same name.
Example
My parsing code in the similar situation was as follows:
NSDictionary *parsedFeed = /* your way to get a dictionary */;
for (NSString *key in parsedFeed) {
id value = [parsedFeed objectForKey:key];
// Don't assign NSNull, it will break assignments to NSString, etc.
if (value && [value isKindOfClass:[NSNull class]])
value = nil;
#try {
[yourCreatedEntity setValue:value forKey:property];
} #catch (NSException *exception) {
// Exception means such attribute is not defined in the class or some other error.
}
}
This code will work in trivial situation, however, it may need to be expanded, depending on your needs:
With some kinds of custom mappings in case you want your JSON value be placed in differently named attribute.
If your JSON has sub-objects or arrays of sub-objects, you will need to detect those cases, for example in setters, and initiate new parsing one level deeper. Otherwise with my example you will face the situation that assigns NSDictionary object to an NSManagedObject.
I don't think it is reasonable to dive into these, more advanced matters in scope of this answer, as it will expand it too much.
I suggest you to use this library : https://github.com/TouchCode/TouchJSON
And then if you want to make a factory to parse json and feed your code data, you can use selectors to call methods to fill all your attributes.
Chances are your JSON data gets converted to an NSDictionary or NSArray (or some combination of the two). Simply extract the key/values from the JSON structure and add them to your entity class.
This lib helps me lot
Features
Attribute and relationship mapping to JSON key paths.
Value transformation using named NSValueTransformer objects.
Object graph preservation.
Support for entity inheritance
Works vice-versa

What is the preferred datatype to parse JSON into in Objective-C?

What is the preferred datatype to parse JSON into in Objective-C? I'm looking for a data type that mirrors the ability to use key=>value style and just array form.
Typically libraries (such as SBJson) will return their parsed results as either an NSArray or an NSDictionary, just depending on if the parsed JSON element was an object or an array.
From SBJsonParser.h:
/**
#brief Return the object represented by the given string
This method converts its input to an NSData object containing UTF8 and calls -objectWithData: with it.
#return The NSArray or NSDictionary represented by the object, or nil if an error occured.
*/
- (id)objectWithString:(NSString *)repr;
In your question you asked "I'm looking for a data type that mirrors the ability to use key=>value", that is by definition exactly what a dictionary is... so, you're probably looking for NSDictionary.
The question doesn't make any sense. The JSON string itself determines what type of object you are going to get when it's deserialized. It can be a string, number, array or dictionary. You have to be prepared to receive any of those. If you use NSJSONSerialization, you'll notice that the decoding methods return id, which means you don't know the type ahead of time. You will have to use isKindOfClass: to figure out what you actually got back.

How can i save JSON objects to Core Data?

I'm a nwebie in Core Data, i have designed a navigation based application and some of the data i use are created on run time(come from a URL via JSON). I took a few tutorials an searched for almost a day but haven't still realized how to save the incoming JSON data to the Entity (or event?) in my Core Data model. I fetch the data in the DetailViewController class and i need to save this data to Core Data(I have prepared an Entity with 7 properties). Can anyone please help?(If you know a good tutorial or sample code i will be pleased)
EDIT This may be a little specific but i really have trouble with and need just a little help.
My data comes to the app from a kind of restful server(i wrote it in PHP), firstly user enters his/her login informations(which i have saved to the database on server before) and when the response data comes i will use different elements of it in differen views(for example the user_id will be used on a view and the buttonData etc on other views). My question is, how will i save JSON data into my core data model(has tree Entities for the moment). Thanks in advance
Note: I lokked arround a lot but couldn't find any answer&tutorial about an app like mine
The best way to do that would be to create entities corresponding to JSON structure. Easiest was is when each JSON object becomes an entity, and arrays become arrays of entities. Be reasonable, however, and don't introduce too much overkill for JSON subobjects that are essentially part of its superobject.
When you have created entities, you can start off with the parsing and translation. Use some JSON framework (starting from iOS5 there's one from Apple) and parse JSON string into object tree, where root item is either an NSArray or NSDictionary, and subelements will be NSArray, NSDictionary, NSNumber, NSString or NSNull.
Go over them one by one in iterational loops and assign according values to your core data entity attributes. You can make use of NSKeyValueCoding here and avoid too much manual mapping of the attribute names. If your JSON attributes are of the same name as entity attributes, you'll be able to just go over all dictionary elements and parse them into attributes of the same name.
Example
My parsing code in the similar situation was as follows:
NSDictionary *parsedFeed = /* your way to get a dictionary */;
for (NSString *key in parsedFeed) {
id value = [parsedFeed objectForKey:key];
// Don't assign NSNull, it will break assignments to NSString, etc.
if (value && [value isKindOfClass:[NSNull class]])
value = nil;
#try {
[yourCreatedEntity setValue:value forKey:property];
} #catch (NSException *exception) {
// Exception means such attribute is not defined in the class or some other error.
}
}
This code will work in trivial situation, however, it may need to be expanded, depending on your needs:
With some kinds of custom mappings in case you want your JSON value be placed in differently named attribute.
If your JSON has sub-objects or arrays of sub-objects, you will need to detect those cases, for example in setters, and initiate new parsing one level deeper. Otherwise with my example you will face the situation that assigns NSDictionary object to an NSManagedObject.
I don't think it is reasonable to dive into these, more advanced matters in scope of this answer, as it will expand it too much.
I suggest you to use this library : https://github.com/TouchCode/TouchJSON
And then if you want to make a factory to parse json and feed your code data, you can use selectors to call methods to fill all your attributes.
Chances are your JSON data gets converted to an NSDictionary or NSArray (or some combination of the two). Simply extract the key/values from the JSON structure and add them to your entity class.
This lib helps me lot
Features
Attribute and relationship mapping to JSON key paths.
Value transformation using named NSValueTransformer objects.
Object graph preservation.
Support for entity inheritance
Works vice-versa

CoreData Optional Relationships and JSON null

I have a CoreData model with 2 objects. The first object (Images) contains a list of image names. The second object (Book) has a relationship with a field from the Images object called imageId. The data type is set to int16 and is marked optional with a default value of 0, as not every book will have an image.
I request a JSON representation of the Book object from a WCF service. One of the book objects returned has "ImageId" : null as its value. So when converting the JSON object into a managed object in Objective-C I get the following error message:
Unacceptable type of value for attribute: property = "imageId"; desired type = NSNumber; given type = NSNull; value =
How do you handle this conversion? I thought of checking for null and then setting the value to 0 but this doesn't seem correct.
Many thanks.
*UPDATE *
In the process of implementing Daniels solution I discovered that other fields could also be returned from the service as null. Is it therefore possible to modify the NSDictionary category to enable it to traverse itself and replace any instance of with nil? I am using jsonKit as my JSON parser and it seems to return the parsed result as a NSMutableDictionary with NSDictionary objects representing my JSON objects. I have spent much of the day trying to modify my objects but as they are returned as NSDictionaries they are immutable. I could simply use Daniels solution on every field that needed checking for however if the service changed and another field was returned as then this would break my app. Alternatively I could implement Daniels solution on every field just incase it was ever but not sure if thats a good solution especially for performance.
Some JSON libraries let you set an option so that JSON nulls are simply omitted from the dictionary as opposed to using NSNull. If you do that, then it will work because [theDict objectForKey:#"imageID"] will return nil.
But other than that, the right thing to do is look out for NSNull explicitly. Making an NSDictionary category is a handy way to do it:
#implementation NSDictionary (DDNullGetter)
- (id)nonNullObjectForKey:(id)key
{
id val = [self objectForKey:key];
return (val == [NSNull null] ? nil : val);
}
#end