Would nsdictionary be a good data type to use for storing long string values as values and names of those descriptions for keys? Or would a different data type be more effective? I am using it for animals, and having and array hold all the data then using a dictionary to point to the name and description of the animal. I'm just curious if this is used for smaller data like states and capitals
Or should I just use a #Define #"rhino description"
[Animal animalObj:#"rhino" location:#"the water" description:[[self setGenericAnimals] valueForKey:#"Rhino"]]
NSDictionary is OK for this. Whats great about using NSDictionary is you can save your data as JSON in a sperate file and then serialzie it into a NSDictonary when you need it. This would make it easier for you to manage all your data and it seperates it from your application.
this is a good start on how to convert JSON into a NSdictionary.
http://www.raywenderlich.com/5492/working-with-json-in-ios-5
Remember though that the entire NSDictionary must fit into memory so if your going to have thousands of strings you might want to separate that into different JSON files and then serialize them into Dictionaries when you need them.
Another thing to remember is that if you want to do simple comparisons and sorting options on objects you are better using CoreData as this allows you to store lots of strings and easily access them.
Related
I'm very new with Objective C and I inherited a project to learn and expand from. The end goal is to move to Swift in the long run, but for now I need to continue with Obj C.
I have a very large and complex JSON of roughly 4000 lines of variables and sub objects.
In Android I am able to easily deserialise this JSON to an object which can be saved easily with Room by essentially converting complex parts into separate JSON strings and deserialising them all when needed.
How should I approach this in Obj C? I found https://quicktype.io which allowed me to easily get a generated class for the JSON structure, so that part is done.
I need to save this data in CoreData and then retrieve all of it when needed. I don't need to get specific parts of the data, so it doesn't matter if it comes to saving the whole thing as a String.
Is there a way to easily generate table entities based on a class, or should I just mash it together as a String? What is the best way here?
Sorry that I can't give any code examples, because I don't have much to go on.
I'm making a plist to hold genre synonyms. The list of synonyms for a given genre doesn't have any inherent order to it.
Should I use an array (which implies an order that doesn't exist) or a dictionary (which implies there's a corresponding value for each key, which doesn't exist).
Simply put--to store an unordered set in a plist, how should I represent it and why?
(To clarify: If there were a Set data structure in the plist editor, I would use that, but I only have Array and Dictionary to choose from.)
More details: I'm going to be looking up by the primary representation of the genre, thus the outer data structure in the plist has to be a dictionary.
But then for the synonyms, the only operation necessary is to enumerate them using a block.
So either an array or a dictionary will do. However, I'm concerned that using an array will imply an order that doesn't have any semantic meaning. On the other hand, is it a common occurrence to have dictionaries in plists that don't have a corresponding value?
Editing again to respond to Josh's comments:
I like your idea of converting into an NSSet after reading in the plist. However, I could still do that with a dictionary, right? So not sure why an array is the obvious choice.
If someone else edits the plist, they might think there's a meaning to the order, when in reality, the ordering is arbitrary.
Surprised no-one has defended using a dictionary instead of an array. Is there a reason a dictionary shouldn't be used in a plist for this purpose?
If you don't care about order, then the arbitrary order you get from building an array is equivalent to the arbitrary order you'd get by using a set. You can also very easily convert an array in a plist to an NSSet after reading it back: +[NSSet setWithArray:]
So use an array.
I would just use an array, since you say there's no corresponding key for a dictionary entry.
At the same time, if you're typing in a large number of entries into plist files (www), your fingers may get tired from dealing with the raw XML or plist editor stuff. You might want to consider a different way to save your synonyms?
Use an NSArray if lookup by item is not needed. If lookup is needed use an NSDictionary.
I have a JSON data feed where the value is a hash if single value and is an array if there are multiple values (see JSON data below).
JSON data:
# multiple values in option
{"options":{"option":[{"$t":"hasShots"},{"$t":"housebroken"}]}
# single value in option
{"options":{"option":{"$t":"hasShots"}}
I can do a check to see if the value is a hash or array using is_a? in Ruby, then extract the data accordingly and convert it to an object. Is this how it would typically be done or is there a better, more elegant way to code it in Ruby?
(NB: I figure this is such a common thing that there might be good solution to handling it. I google but it kept giving me how to parse JSON data's and creating JSON in Rails.)
I can do a check using is_a?. Is this how it would typically be done?
That's how I would do it! I think the more common scenario is for the JSON (or whatever) to have a consistent design, and have the objects in an array even if there's just one.
I have an NSMutableArray of objects that I would like to persist between user sessions. Each object has an NSInteger property, and I would like to be able to access all of the objects for calculations using that property (averages, mins, maxes, etc.)
Would it be better to store that array into a Core Data database or just store my objects individually into the database?
EDIT: The array should hold no more than 1,000 items.
Depends on the size. If it's simple just archive the array to a file
Edited to add
If all you want to persist is an array you don't need to use the archiver methods, you can do it directly.
Imagine you have a file URL in your app's Documents directory called persistentURL which you want to use to save and read your array from.
All you need to do to persist the array is:
[yourArray writeToURL:persistentURL atomically:YES];
And when you want to read the data back into an array it's as simple as:
yourArray = [NSArray arrayWithContentsOfURL:persistentURL];
You can use this method here because the array contains only NSNumbers which are property list objects (i.e. objects that can be put directly into a plist).
NSArray and NSMutableArray can't contain integers directly. It has to contain NSNumber objects.
Anyway, I'd just use NSCoding. Try the methods archiveRootObject:toFile: (which writes directly to a file) or archivedDataWithRootObject (which converts the content to a byte-stream in NSData).
For <=1000 items it should be fast enough.
If you're reading and writing the array enough, you might want to consider using a malloc'ed C array of "long"s, and saving that as bytes to a file. That would be faster, and you could read/write values to your C array easily, instead of having to do object replacement. On the other hand resizing the array or inserting values is a pain with a C array, and you also have to be aware of data size and byte ordering issues if you will ever transfer this data between devices.
Edit: I just wrote a little test, and writing an NSArray of 1,000 NSNumbers to a file with archiveRootObject:toFile: takes about 0.0038 seconds on on old iPhone 4 I have around for testing. That's the slowest machine that supports iOS 7, and it's 3.8 THOUSANDTHS of a second, to write 1,000 items. So writing an array of 10,000 items should take 3.8 hundredths of a second or less.
Unless you are reading and writing this array many times a second in a loop, using archiveRootObject:toFile: is plenty fast enough.
Personally, I would use the following to store that array:
[[NSUserDefaults standardUserDefaults] setObject:myArray ForKey:#"myArray"]
and retrieve it anywhere in the app:
NSMutableArray *myArray = [[[NSUserDefaults standardUserDefaults] objectForKey:#"myArray"] mutableCopy];
That seems to me to be the easiest way to persist that data. You can store the mutable array in NSUser defaults, and I believe you'll need to create a mutable copy of it when you retrieve it later on to be able to continue to make changes to it.
I have an app that feature "pages". Each page can have n number of images, depending on user preference. To store the images and associate the image with the correct view etc, I am building a dictionary for each image, then storing that dictionary in an array of image dictionaries, which I save to core data as binary data. I am storing the image itself as an object in the dictionary, like below. Is this an efficient and safe way to do this? Seems to work ok...
imageDictionay = [NSMutableDictionary dictionaryWithObjectsAndKeys:image, #"image", imageTag, #"tag", imageTransformString, #"transform", nil];
That way will certainly work, but I would personally create another entity for ImageInfo like so:
If you are going to have a dictionary with the same three keys, it makes more sense to me to have an entity with those three attributes.
Also, if you are really worried about performance, you could also write the image to disk and just put a string in Core Data to tell you where the image is stored.