I am using mantle framework to parse JSON file.
My JSON object Looks like this
[{
key:value
key:value
},
{
key:value
key:value
} ]
My object is array that doesn't have key.
How could we parse this array? How should the JSONKeyPathsByPropertyKey method be implemented?
As mentiond on the Library description
This method Specifies how to map property keys to different key paths
in JSON
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
return #{
#"items" : #"",
};
So how could we map array property to JSON object that doesn't have a key ?
I assume, You are getting an array in response of an API call and you want to parse it.
So as per your JSON. You need to create a MTLModel subclass for the type of objects in the array.
Then you can parse the array and create the models of the object types in array. Like this:
NSArray *objects = [MTLJSONAdapter modelsOfClass:[model class] fromJSONArray:[PASS THE ARRAY] error:nil];
Hope that helps.
Related
I have NSDictionary filled with many objects. I have sorted the keys in a desired pattern and now I have the keys only in a new NSArray. How to apply the changes so the order of the elements in the array to be reflected in the dictionary?
For ex. NSArray -> ["D" , "B" , "A" , "C"] this order I want to apply to the keys in the dictionary.
NSDictionary -> {{"A" : <something>} , {"B" : <something>} , {"C" : <something>} , {"D" : <something>}}
You don't. You iterate over the keys in the array and then pull out the data from the dictionary.
for (NSString *key in sortedKeys) {
id value = dictionary[key];
// do something...
}
If you need ordering you might consider using NSOrderedSet or rolling your own data structure to do this. For example, I have created data structures that use both NSIndexSet and NSDictionary to provide key/value storage with faster sorted enumeration.
I have an array from a plist and each value contains an key and a string and a secondary array that I get from a json file online. I want to order the secondary array based on the keys in the first array.
I want to achieve something like this:
array1:
Item0 - EUR
- String
Item1 - USD
- String
Item2 - AUD
- String
etc
array2:
Item0 - AUD
- 123.242
Item1 - EUR
- 535.123
Item2 - USD
- 325.646
etc
I have the same key index on both but I want to get the value for the key index from array2 based on the order of the key index in array1.
I have researched online but I cannot find a suitable solution that I can understand how to implement it.
How can I implement this?
Here is the plist file - https://gist.github.com/iulianvarzaru/11c400ba1edf4a165082
And the json file - https://gist.github.com/iulianvarzaru/1915e02a9201c57f49b3
Given that the JSON file you've linked to doesn't contain an array but a dictionary, you can simply iterate over array1 from the plist file. Each element of that array is a dictionary with a "Cod" key and a "Descriere" key. Get the value for the "Cod" key and then simply use that value as the key into the dictionary from the JSON file.
NSDictionary* jsonFileDict = ...;
NSDictionary* jsonFileInnerDict = jsonFileDict[#"rate"];
for (NSDictionary* dict in array1)
{
NSString* code = dict[#"Cod"];
NSNumber* jsonNumber = jsonFileInnerDict[code];
// Do something with jsonNumber
}
It sounds like these are key-value pairs, in which case, you can convert it to a Map, and then do direct lookups.
If you can manipulate the JSON file as JSON, then it reduces a conversion, but may not be the most efficient implementation.
Caveats:
This method assumes that you wont have key overloading (which is possible in a numeric array, but not in a map)
This requires a conversion from one data structure to another
EDIT: (due to increased information by OP).
The JSON file you receive doesn't contain an array, it contains an object. Thus, all the values are direct-lookup. So, you can traverse your array in Obj-c, and directly access the corresponding values in the JSON.
Sorry about the lack of actual code-samples.
You are dealing with a dictionary in the response, not an array.
You should transform it to something like
{
#"currency": #"EUR",
#"value": 123.45
}
create and sort it it like
NSArray *keys = #[#"EUR",#"USD",#"AUD"];
NSDictionary *dict = #{#"AUD":#(123.242), #"EUR": #(535.123), #"USD": #(325.646)};
NSMutableArray *result = [#[] mutableCopy];
for (NSString *key in keys) {
[result addObject:#{#"value":dict[key], #"currency": key}];
}
NSLog(#"%#", result);
(
{
currency = EUR;
value = "535.123";
},
{
currency = USD;
value = "325.646";
},
{
currency = AUD;
value = "123.242";
}
)
Or write a model class that can handle this information.
I am deserializing data into a dictionary, but the result is a nested dictionary so it looks like:
{"0":{"key1":"value1","key2":"value2"},
{"1":{"key1":"value1","key2":"value2"},
{"2":{"key1":"value1","key2":"value2"}}
I want to use this in a tableview so how would I go about turning that dictionary into an Array where each objet in the array is a dictionary with the value pairs?
I want to be able to step through the array, and reference the value pairs for each row of the array.
Thanks!
for (NSDictionary *dict in outerDictionary.allValues) {
[tableArray addObject:dict];
}
Indeed, or simpler:
tableArray = outerDictionary.allValues;
{
"success":true,
"listings":
{
"50831582253b4acf09000000":
{
"id":"50831582253b4acf09000000",
"title":"fddfds",
"assets":[],
"discussions":[]
}
},
"displaymessage":"1 Listings Found"
}
I am still struggling between dictionaries and arrays. What would make the above an Array?
Thanks
There's a pretty big difference between dictionaries and arrays. Dictionaries store data entries in relation to a keys you specify on instantiation. For example:
NSDictionary *myDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:#"object1",#"key1",#"object2",#"key2", nil];
This alloc/inits a dictionary and sets "object1" for "key1" and "object2" for "key2", so then if you wanted to ask for the value of "key1" you could access it with the following.
NSLog(#"%#",[myDictionary objectForKey:#"key1"]);
Objects in a dictionary can be arrays, dictionaries, booleans, data, dates, numbers and strings.
On the other hand, arrays store data by the datas index within the array:
NSArray *myArray = [[NSArray alloc] initWithObjects:#"object1",#"object2",#"object3", nil];
You can then access the a specific bit of data from within the array by asking for objectAtIndex:, ex:
NSLog(#"%#",[myArray objectAtIndex:1]);
Which will return "object2" because the first index in an array is always "0".
Check the JSON docs
JSON Arrays are represented by square brackets
[ "object1", "object2" ]
JSON arrays are normally represented in Objective-C by NSArray. This matches up with the new literal syntax
#[ #"object1", #"object2" ]
JSON Objects are represented by curly brackets
{ "key" : "value" }
JSON objects are normally represented in Objective-C by NSDictionary. This also matches up with the new literal syntax
#{ #"key" : #"value" }
As you can probably tell, the entities or "cells" in the list are separated by commas (,)
In a serialized dictionary, an entity is broken into a key:value pair by a colon (:)
"success":true
Where the first part in quotes before the colon is the key, and the second part is the value that corresponds to that key.
A serialized array might look something like this:
{"hello", "goodbye", "world", "words", "friendship"}
Notice that entities are still separated by commas, but there are no colons outside of quotes.
Another key difference is that in dictionaries, keys must be unique, so you shouldn't have something like this:
{"success":true, ..., "success":false}
whereas in an array, elements do not have to be unique:
{"hello", "hello", "goodbye"}
Hope this helps =)
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