Serialize an Array of data - iphone

I currently write to and read from an array of data, and use the index of each element to achieve something. I need a way to store this array, I looked at the user defaults, but that stores a dictionary, with retieval using keys. I will not know what key was stored.
What is the best was to store ths array of data on the iphone?
Regards

NSKeyedArchiver, a concrete subclass
of NSCoder, provides a way to encode
objects (and scalar values) into an
architecture-independent format that
can be stored in a file.
So you can serialize anything you like to a file:
// need a path
- (NSString*) getPath
{
NSString* path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
return [path stringByAppendingPathComponent:#"someInfo"];
}
// save an array
- (void) save:(NSArray*)array
{
[NSKeyedArchiver archiveRootObject:array toFile:[self getPath]];
}
// get that array back
- (NSArray*) load
{
return [NSKeyedUnarchiver unarchiveObjectWithFile:[self getPath]];
}
You might want to serialize a dictionary of arrays if you have more than one you want to store.

It is possible to store an array in NSUserDefaults. It does however depend on the kind of objects the array holds. NSKeyedArchiver is another good option, as is storing the array as a plist. It could even be that CoreData is the best choice for you. It all depends on the expected size of your data and how you use it. NSKeyedArchiver seems a fair enough middle ground for many situations, but to answer you question more info is needed.

Related

Saving an NSDictionary to MySQL with JSON

I want to save the following NSDictionary to a MySQL database:
NSDictionary notesDictionary:
object: NSString key:"note"
object: NSArray key:'subNotes"
object: NSString key:"publishDate"
The tricky part is that the NSArray subNotes is just another array of dictionaries with the same keys as above. So a note is put in a dictionary, which in turn has an array of dictionaries, which in turn has an array of dictionaries, and so on (each note has a subnote, and subnotes have subnotes, and so on).
I'm new to MySQL, so the following is the solution I've found to storing the above dictionary in the database:
NSString *jsonString = [notesDictionary JSONRepresentation];
Then I just store the string into the database, and retrieve it with similar methods. This works, but I'm not sure if it scales. If I had a 1000 notes, would this cause any performance setbacks, as the entire dictionary is saved as a string, and then later converted from a string back to a dictionary. Is this a good, fast, and secure way? Or is there something else I should be looking into?
JSON is a perfectly good serialization format. I wouldn't worry about performance or anything like that. The only concern I'd have is making sure the MySQL column is set up to take an arbitrarily long string. (Not sure how to do that in MySQL offhand, but it shouldn't be too tough.)

How to use my Class with PList in objective-c?

I have a Class for handling my data in my project, and now I need to store the data.
I'd like to use a Plist but I'm a bit unsure of how to start.
My class is pretty simple - 6 pieces of data, flat (no hierarchy).
I want my app to start with no data, so can I assume that I should create the PList programmatically once the User creates their first piece of data? (That is, don't create a .plist file in 'Supporting Files' prior to distribution?)
Then, when the app starts the next time, read the data and create an NSMUtableArray array of Class instances?
To create a property list, all you need to do is use appropriate types (i.e. those that support the property list format: NSData, NSString, NSDictionary, NSNumber, NSDate, NSArray), store them in a single container, and tell the containing object to write itself to a file. To read the data, you can initialize that same type using a path. For example:
// writing some data to a property list
NSString *somePath = ... // replace ... with the path where you want to store the plist file
NSMutableDictionary myDict = [NSMutableDictionary dictionary];
[myDict setObject:#"Caleb" forKey:#"name"];
[myDict setObject:[NSNumber numberWithInt:240] forKey:#"cholesterolOrIQ"];
[myDict writeToFile:somePath atomically:YES];
// reading the file again
NSDictionary *readDict = [NSDictionary dictionaryWithContentsOfFile:somePath];
The simplest way is to simple save an NSArray or NSDictionary to disk. Caleb's answer goes into detail there so I won't repeat it, other than to say you might have to convert a non-compatible object like NSColor to an property list object like NSData. It's up to you to do this each time you save or load your data.
NSKeyedArchiver and NSKeyedUnarchiver give you a little more control over the process, but work pretty much the same way. You provide (or get back) a plist compatible root object (usually an NSDictionary) that contains your data. I recommend creating a dictionary that includes your data structure as well as an arbitrary number (your app's build number is a good choice) to use as a version indicator. This way if you ever update your data model you can easily determine if you need to do anything to convert it to the new version.
If you're putting your own objects into the data file, look into NSCoding. The protocol gives you two methods using NSKeyedArchiver and NSKeyedUnarchiver to save and restore your data. This is by far the most straightforward approach if your data model consists of anything more than a few simple strings and numbers, since you're dealing with your own native objects. In your case, you would have your data class implement NSCoding and use the NSKeyedArchiver and NSKeyedUnarchiver methods to encode your six instance variables. When it's time to save or load, pack the instance of your class into an NSDictionary (along with a versioning number as I mentioned above) and call NSKeyedArchiver's archiveRootObject:toFile:. Your save an load methods deal only with your own data object, which makes things easy for you. The common pitfall to watch out for here is if your custom data object contains other custom object. This is fine, but you have to make sure every object that's going to be saved has its own NSCoding implementation.
Two things you can do:
Use NSUserDefaults:
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/Reference/Reference.html
The objectForKey method is the one you want to use to store your class. But, as pointed out in the comments, this shouldn't really be used for storing lots of user data; it's best for saving preferences.
For storing more data, you might want to look at Core Data. It's more complex, but should be better suited to your needs. Here's a tutorial on it:
http://mobile.tutsplus.com/tutorials/iphone/iphone-core-data/
Neither of these seems best for your simple application, but I leave this answer up since it gives alternatives for saving data to the iPhone.

How can I save Array of Class Objects in to a Plist(Iphone Development)

I have a question related to save an array of Class objects to a plist And then get it back.
For example i have a class "A" with two Nsstring and some int values.
I have an array of Class A objects.
How can i save this array in to plist.
I can Done store a simple Array(Array of Strings) in to Plist.There is No Error.
But When I store this "Array of Objects" It cant be done.
Thanks in Advance.
First convert your NSArray to NSDictionary as given here.
Then use NSDictionary's writeToFile:atomically: to store that as Plist.
For this, your class must be conform to NSCoding protocol.
Or otherwise, you can write your NSArray itself directly to plist without converting to NSDictionary. But anyhow, the class should conform to NSCoding protocol.
Indicate the .plist path to the class variable correctly
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"patientList.plist"];
[myPatients writeToFile:path atomically:YES];
use the above i hope this wil be usefull
You cant save objects to Plists. It wont ever work, you would only ever be able to save internal variables to a plist. It you want to save objects, you need to first make your class NSCoding compliant. This is a good link explaining it http://samsoff.es/posts/archiving-objective-c-objects-with-nscoding But it doesn't mention objects within objects but its basically just another level. You need to make sure any object that is within an object you are saving is NSCoding compliant as well, all the way down the chain. Then you need to use NSKeyedArchiver to save them. I wrote a nice manager class that will take care of all of this for you as long as your objects ar NSCoding compliant. its available right here https://github.com/caranicas/Save-Manager enjoy!

Problem with savin data!

I have a UitableView and its a checklist. I want to be able to save data when the user leaves the view. Then when the view is opened back up i want there to be the saved data. When i say saved data i mean that the table view is able to add and delete cells also i want to be able to save the checkmarks. Could somebody please provide me with a way or an idea on how to do this?
i know i can save data with:
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
and then save the data to defaults, but i need know how on saving the table view's cells that are add and or deleted! also i would like to know how to save the checkmarks!
Thank you,
Kurt
Sounds like core data would be good here
http://developer.apple.com/library/ios/#documentation/DataManagement/Devpedia-CoreData/coreDataOverview.html
I would suggest using either Core Data, or NSCoding. NSCoding allows you to encode an object as NSData, and reload a replica of that object from NSData.
For instance, saving and loading an array of strings through NSCoding would be something like this:
NSArray * array = [NSArray arrayWithObjects:#"This", #"Is", #"A", #"Test"];
NSData * encoded = [NSKeyedArchiver archivedDataWithRootObject:array];
// save the encoded data to a file...
// load the encoded data from a file...
NSArray * decodedArray = [NSKeyedUnarchiver unarchiveObjectWithData:encoded];
Of course, you will need to implement some NSCoding stuff yourself if you plan on using classes more complicated than NSDictionary, NSArray, NSString, etc.
Documentation for NSKeyedArchiver can be found here. You can also find documentation for the NSCoding protocol here.

Is it possible to store an NSMutableArray together with all its contents into a file and restore it later from there?

Some kind of serialization available in iPhone OS? Is that practically possible or should I quickly forget about that?
I am making a tiny app that stores some inputs in an NSMutableArray. When the user leaves, the inputs should stay alive until he/she returns to continue adding or removing stuff to/from that array.
When the app quits, there must be some way to store all the stuff in the array in a file. Or must I iterate over it, rip everything out and write it i.e. comma-separated somewhere, then the next time go in again, read the stuff in, and iterate over the lines in the file to make an array with that data? That would be hard like a brick. How to?
The easy way, since you already have an NSArray object is to write the array to disk using
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)flag
and read it back in with:
- (id)initWithContentsOfFile:(NSString *)aPath
or
+ (id)arrayWithContentsOfFile:(NSString *)aPath
You can also use NSCoder.
You can probably search sof for the right code.
So long as the objects in the array implement NSCoding (NSString and NSValue do; if you're storing your own objects it's relatively straightforward), you can use:
[NSKeyedArchiver archiveRootObject: array toFile: filePath];
to save and:
array = [NSKeyedUnarchiver unarchiveObjectWithFile: filePath];
to load.
You can similarly load/save to NSData.
The iPhone SDK is designed to store data using SQLite tables.
You can use NSPropertyListSeralization, since NSArray is a type of property list. You can find more information here.