Storing an array of 500 NSStrings in an iPhone app - objective-c

I want to make an iPhone app that fetches up to 500 NSStrings from a server, and then it stores that data for later use.
I believe that my options are to use NSUserDefaults, store them in an SQLite database, or store them in an XML file.
Is that correct? Is an array of 500 NSStrings large? Which method should I use?

NSUserDefaults is meant for small amounts of application state and/or preferences.
SQLite is fine, but might be overkill if you're not using any RDBMS features. Internally, Core Data uses SQLite. If you're not interested in the object-graph, then Core Data is incredible overkill (and has a ton of overhead).
XML is meant for storing arbitrarily structured data. Is there any inherent structure to your data or it purely just a list of 500 strings? If there's no structure, then XML is overkill and you have to parse it, which means a non-trivial amount of code.
Two more options you didn't mention are: plist and NSKeyedArchiver. I'll leave it to you to read up on those.
Personally, I'd just go with a text file, but with the proviso that you haven't given enough information about the nature of the data or what you're going to do with it.

You can use
NSArray initWithContentsOfFile:
and
NSArray writeToFile:
to easily store your Strings in a file.

Related

Saving model object into SQL DB

I am reading several tutorials on how to use an SQL database with Cocoa, and it seems quite easy. I already took a look at a few wrappers too, but I can't find anywhere a way to save objects.
Is it correct to conform my model object to the NSCoding protocol, and just save the NSKeyedArchiver as an NSData object into the DB?
Should I do differently? Which is the best way?
You can use NSKeyedArchive too, but is not the best solution imho. Is like storing all data in a platform independent "database" an xml file. It wasn't created for that, it in't optimized for that.
I would create a NSSqlArchieve and map those fields which I want as how I want in native database, because: in different databases you can have custom fields, custom type fields , which myabe improve a select or other database operation. Or you just want to take advatage of some system table/data and can't find a mapping or is to slow or other problems.
NSData can be stored / retrieved to a Blob/Clob, since is binary data.
But all data convert to binary format and store it to database.... why to store there and why not into a file. Database was invented to store and make query from data.

Storing UIImage as Transformable attribute in Core Data

I am currently working on an app in which I want to store a UIImage in one of my Core Data entities. I have read that in iOS 5 UIImage now conforms to a protocol called NSCoding, so conversion methods from NSData are no longer necessary. I have set my image attribute to Transformable, and my program works wonderfully when I retrieve the image.
Is this a safe and secure method to store a UIImage that will allow for future below 30 second migrations? Will it be good performance-wise? I have also read about the Binary Data attribute type, that allows files to be stored in the file system, rather than the database. If this is a better alternative, how would one implement it?
Migration time depends on the entire database schema and size, not just storing a UIImage. No one can answer that question.
Performance is relative. If you store it externally, it will generally be better performance-wise, because it's not in the database itself, but there are lots of other performance issues, like managing the fault, especially if you store it as a direct attribute as opposed to a relationship. Also, it depends on your usage. No single solution is best for all circumstance.
You must profile your application use cases, and make the decisions that best serve the performance characteristics of your application.
For any non-trivial binary data, you should indeed let Core Data manage that as external data. It's simple. In the data model GUI, check the box that says "Store in External Record File."
Sorry, I didn't notice you said that you were already perfectly aware of how to encode images. I would not recommend storing them in the database, but good luck.
Previously: Storing UIImage in Core Data with the new External Storage flag
The comments on that thread about bugs suggest it is still probably a safe idea to just store images on the filesystem yourself.

What are the downsides of plain text files as configuration files with only a few values in iOS?

Why use plists and xml files? If I only want to store a few values, is it okay to use plain text files or does this go against Objective-C best practices?
-------EDIT-------
I'm not sure if this should go in a separate post or not, so I'll just put it here...
If I'm making an app where a user can design a cupcake and save it with their preferences (color, flavor, size), which method should I use. I imagine my users aren't going to make hundreds of designs, but some will inevitably make a large number.
I'd say it's fine, but considering how easy they make it to read plist files, my question would be why bother?
The main reason that plists are commonly used is because the native APIs can handle these easily. You can load a NSArray/NSDictionary directly from a plist with one command.
SQL databases are used when you are going to have many occurrences of similar data. For example, if you need to record contacts for a social app, you would use a database that could contain the id, name, age, gender, phone number, email, etc.
Other than these, there are custom binary formats, but these are specialized for whatever project is being worked on. Depending on what you need to accomplish, a text file could work for you, but there may be better answers. There is nothing wrong with using text files, but these are not commonly used as you would have to write your own methods to parse them. Really, I would need to know more about what type of data you will be storing before I could tell you which option would be best.
An edit to answer your edit:
For this, the best thing to do would be to use a SQL database, as every cupcake is going to have various properties, such as name, type of cake mix used, type of frosting, color of frosting, sprinkles yes/no, etc. This is perfect for a SQL database, because dbs have named colums (ie "name", "mixType", etc), and each row in the table will have different values for each of these columns.
This could also be implemented with a plist, but it wouldn't be as efficient, and it would use more disk space (although not much if youre just using it for cupcakes). I assume that you have a Cupcake class, so you could just implement a load function like this:
+(id)cupcakeWithContentsOfFile:(NSString*)file {
if((self = [super init])) {
NSDictionary* plist = [NSDictionary dictionaryWithContentsOfFile:file];
self.flavor = [plist objectForKey:#"flavor"];
// Etc.
}
return self;
}
This is an interesting question. I actually have an app out there that DOES indeed use simple text files for data that the app uses. Because the original code came from a windows / mac program, and I wanted to keep the data files consistent, Windows doesnt provide pfile type operation. I wrote all of the code on windows to read in the files, and since it was all ANSI-C it transported to MacOS X quite nicely.
When it came to porting it over to the iPhone and iPad, it still was just as easy to port the code then to re-write not only the data files into PList format, but also the PList reading code.
For All apps that I have begun from scratch that arent windows bound also, I have used PLists though.
This is actually an issue that I go back and forth on. PList and / or XML reading and processing is certainly NOT going to be as high of performance as a well designed text file format as both are bloated due to all of the excess tags that may or may not be necessary. If you are trying to develope a single data file that has many types of data, than this could be the simpler approach, but if you are looking for less datasize, and maybe faster execution, then formatting your own file may be much better. I know this isnt a definitive answer.
So in the end, it isnt a "best practices" sort of thing, but really a preference type of thing.

How should I store a bunch of data locally to display on a UITableView?

I have to display a lot of text preferably pre-formatted or formatted with NSString methods. Each row will have a detailed screen. In the detailed screen another UITableView will have sections for lets say "Definition", "Examples" etc each with only one row. In these rows I will be displaying the text, which spans multiple lines. Should I store all the text in a SQLite database like a column for each section? Are there other ways to store data locally?
You have quite a few different ways to store application data on your iPhone:
Using Flat Files
These are files that contain data in the format you decide it would be best to store it. They are useful for persisting small bits of text data that don't require a complicated structure and a strong relational organization in order to make sense.
Using Plist files
Property list files already have a key-value structure in place, that you can use to your advantage if your data lends itself well to this format. Native data types, such as NSDictionary and NSarray can be serialized and deserialized easily to and from this format.
Storing key-value data in NSUserDefaults
Typically used to store application settings and other small amount of data, NSUserDefaults are useful for holding simple data types without excessive complications.
Storing Information in an SQL Database
Useful for when your data is strongly structured and relational and you want to avoid rolling your own file-based data storage structure for time and performance reasons. The SQL language is a powerful tool for retrieving and persisting relational information and you can manage the complexity of your implementation by resorting to wrappers around SQLite, such as FMDB.
Using Core Data
If you plan on persisting and managing a complicated, dynamic object graph, without worrying on how to serialize and deserialize it from storage yourself, Core Data is your best bet. It can help you in many ways, from change tracking and undo support to relational structure maintenance and migration.
Here is a detailed Oreilly article explaining in more detail the particularities of most of these methods, a great read if you want to develop a solid understanding of the fundamentals.
Some methods are...
Core Data
Write to NSUserDefaults
Write to a file, like for example an NSDictionary to a plist
If all you're storing is a bunch of strings, it might make sense for you to keep it simple and just use NSUserDefaults or make a plist file and load it into an NSDictionary when you start your app. If you have actual objects with relationships and sub properties, then I'd look into core data.

Objective C Data Caching on iOS

I am pulling data from an API and then building out my data objects with it. I want to cache this data for the future. I have been storing the string from the api in NSUserDefaults and then re-parsing it each time the app loads. This works, but it really seems like the wrong way to go about it.
How can I do this?
Have you noticed the NSCache?
An NSCache object is a mutable collection that stores key-value pairs, similar to an NSDictionary object. The NSCache class provides a programmatic interface to adding and removing objects and setting eviction policies based on the total cost and number of objects in the cache...
Personally I'm quite fond of the EGOCache classes, I use them quite a lot in my projects:
https://github.com/enormego/EGOCache
The classes are easy to use, I used to have my own classes with a similar design, but these are just more well-rounded, so I decided to stick with them (don't wanna reinvent the wheel).
There are many different solutions to this problem and there is no "right" way to do it. A few popular options are:
Core Data - Apple's framework for persistence. Very performant, but more difficult.
SQLite - Fast and flexible, but bare bones.
Plists - Basically writing a file to disk, you have to read and write manually.
NSUserDefaults - The lightest weight "key-value" option.
I would encourage you to read up on all four and see which one works best for you.
I vote Core Data
What type of data? If its text/string bases SQLLite would probably be the best.
I'd store the computed/parsed data in either a Core Data store, or in NSData flat files in your application's Documents directory. You're correct that storing that in NSUserDefaults and then re parsing feels a little overkill.