NSDictionary Vs. NSArray - ios

I am reading on objective-c (a nerd ranch book), and I can't help thinking about this question: How do I decide which collection type, NSArray or NSDictionary (both with or w/o their mutable subclasses), to use when reading content from URL?
Let's say am reading JSON data from a PHP script (a scenario am dealing with), which to use? I know it is stated in many references that it depends on structure of data (i.e. JSON), but could a clear outline of the two structures be outlined?
Thank you all for helping :)

NSArray is basically just an ordered collection of objects, which can be accessed by index.
NSDictionary provides access to its objects by key(typically NSStrings, but could be any object type like hash table).
To generate an object graph from a JSON string loaded via a URL, you use NSJSONSerialization, which generates an Objective-C object structure. The resulting object depends on the JSON string. If the top-level element in your JSON is an array (starts with "["), you'll get an NSArray. If the top-level element is a JSON object (starts with "{"), you'll get an NSDictionary.

You want to use NSArray when ever you have a collection of the same type of objects, and NSDictionary when you have attributes on an object.
If you have, lets say a person object containing a name, a phone number and an email you would put it in a dictionary.
Doing so allows the order of the values to be random, and gives you a more reliable code.
If you want to have more then one person you can then put the person objects in an array.
Doing so allow you to iterate the user objects.

"withContentOfURL" or "withContentOfFile" requires the data in the URL or the file to be in a specific format as it is required by Cocoa. JSON is not that format. You can only use these methods if you wrote the data to the file or the URL yourself in the first place, with the same data. If you write an NSArray, you can read an NSArray. If you write an NSDictionary, you can read an NSDictionary. Everything else will fail.

Related

XML to Object Objective C

I'm trying to convert an XML response from Google to a custom object. My question is what's best to use as in NSMutableArray or NSDictionary when you have a multiple values in i.e. <category> or <title> and how to add them.
<category scheme="http://schemas.google.com/spreadsheets/2006"
term="http://schemas.google.com/spreadsheets/2006#spreadsheet"/>
<title type="text">nothing</title>
Marshaling XML onto a NSDictionary will work, however it can result in quite fragile and difficult to maintain code. Two reasons:
It will result - 'magic strings' when requesting data. Any change in this string will propagate throughout the code-base.
It will be difficult to read, and not exhibit the desirable self-documenting features of good OO.
Instead, its strongly recommended to map the XML of a service payload onto a use-case specific Objective-C object. This is aligned with the principle of contract-first development, meaning that any change to the service might only result in a change to this mapping onto the objective-C object.
A nice XML framework is RaptureXML
Create a category on the RXMLElement class and extract the required information. Then to use the element, just:
RXMLElement* element = [RXMLElement elementWith. . . ];
MyDomesticCat* type = [element asCat];
Any XML is ideally a combination on dictionaries and arrays with its root tag initiating a single key dictionary. To take off the overhead of parsing xml to a customized object model you can use the nice framework, XMLReader, available at github.
If you use this framework, your xml parsing becomes as simple as:
NSMutableDictionary* dictionary = [[XMLReader dictionaryForXMLData:<# your xml data #> error:&err] mutableCopy];
NSLog(#"%#",dictionary);
//use dictionary
[dictionary release];
However, you need to pass some well formed xml data as its input. Also you might need to manipulate the content of the parsed dictionary, according to your needs.

Multiple KeyMappers per JSONModel

JSONModel lets you convert a model object into a NSDictionary as following:
NSDictionary *dict = [myJSONModel toDictionary]
It includes all properties of the model (except optional). However, I also need to create multiple dictionaries having only some model fields required for a particular backend operation.
Some fields could be included in multiple dictionaries, so ideally, it would be awesome if I could do something like:
NSDictionary *dictOne = [myJSONModel dictionaryWithKeyMapper:myJSONMapperOne]
NSDictionary *dictTwo = [myJSONModel dictionaryWithKeyMapper:myJSONMapperTwo]
and it only returns the objects that have been mapped in that particular mapper.
I am sure there's nothing like this at present. The keymapper for every class is created only once and then is cached, so you can't changed it programatically. Plus you cannot ignore properties via the keymapper.
JSONModel is built like so that it supposes you always need to do the same transformations when you convert between JSON and your model, this way it can do the performance optimisations it does.
However "toDictionary" is not too complicated, you could try subclassing JSONModel and playing around with implementing a "toDictionaryWithFieldList" that takes in field names list and exports only those fields ... just an idea

Serializing a custom object into NSDictionary or NSArray to use NSJSONSerialization

I've been looking for a way to serialize custom objects with NSJSONSerialization avoiding the use of third-party libraries, and I couldn't find any example. Is there any way of "automatically" create an NSDictionary and NSArray from an object, without having to create it typing in code all the object's member names yourself one by one and setting manually the values? I found a related post, but it is pretty old, things may have now changed.
Thanks
You can use KVC to ask any object for dictionaryWithValuesForKeys: which will give you a dictionary representation of the object.
If you need to change the property / key names then you want to do some mapping and (depending on what you're using the JSON for) you may find RestKit useful.

How to retain order of JSON data retrieved with AFNetworking?

I am using AFNetworking to retrieve JSON data from a web service. Part of the response string I get is:
{"DATA":{"LEASE TYPE":"3 Yrs + 0 renew of 0 Yrs","LANDLORD":"","TENANT":"test comp"...
and so on. The order of the key values in the "DATA" dictionary ("LEASE TYPE","LANDLORD","TENANT"...) is important for presentation purposes. However, when AFNetworking calls NSJSONSerialization's:
+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;
method, the returned dictionary has the keys in a different order.
I notice that the AFJSONRequestOperation object has the server's response stored as an NSString, with everything in the correct order. However I'm not keen on parsing the JSON by hand if I can avoid it.
Can anyone suggest a way that will let me get at / keep the keys in their original order?
Thanks.
If the order is important use an array not a dictionary, dictionaries are be by their nature unordered. Or add an array of dictionary keys in the order desired.
If you have no control over the response that is sent you will have to parse the JSON yourself at least for the ordering.
When you'r creating an NSDictionary, the order will not be the same. I often recognized that dictionaries get ordered by key-name alphabetically.
But when using dictionaries the order doesn't really matter. And they shouldn't!
As the previous answers mentions dictionaries are by nature without order, but you can find here a nice class of OrderedDictionary:
http://www.cocoawithlove.com/2008/12/ordereddictionary-subclassing-cocoa.html
http://projectswithlove.com/projects/OrderedDictionary.zip

How should I store a large number of nested dictionary information in iOS?

I have a large number of nested dictionaries and the leaf (or most nested) dictionaries store integer data and integer keys. All the information remains constant (but may change in a future release). I am currently allocating the dictionaries from constants in code but I feel I should be reading that information from XML or similar. I have read about Core information, plists, databases and archives but I don't want the user to be able to change it, I never want to be able to write it (except maybe during the release procedure) and I never want to display it. I would like to be able to hand edit it before release.
What is the best method to store this constant data?
Basically you need to ship your data in files with the app -
XML or JSON are both suitable for this. When I have had to do something similar I used JSON
It works something like this :
Define your JSON in text file (UTF8) and then use the
NSString initWithContentsOfFile to load file contents into a NSString
You can then use the NSJSONSerialization JSONObjectWithData to give you the top level dictionary for your JSON
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
From this you can extract your NSStrings / NSArrays using NSDictionary objectForKey for your data. Obviously the exact format will depend on your JSON format

Resources