How do I serialize a simple object in iPhone sdk?
Asked Answered
A

3

27

I have a dictionary of objects; they are all POCO objects that should be serializable. What technique should I look at for writing these to disk. I'm looking for the simplest option to write a few lists to save state.

I think I have 3 options.

  1. plist files. However this seems to be limited to only storing predefined objects (strings, numbers etc) not objects (like a person with a name and age).

  2. CoreData. (New in 3.0) This would work well; however my data model would need to change to make this work. This would be a massive rework and I'm not sure if it is worth the effort.

  3. SQLLite. Implement a simple SQL database to read to and from. I have done the least amount of reserch into this one, but I don't want to have to 'rewrite' some of the core data ORM functions.

Atrophy answered 18/5, 2009 at 2:37 Comment(0)
B
14

You do this in the same way you'd do it on Mac OS X: your POCOs must conform to the NSCoding protocol. See here for a conceptual reference, and here for the NSCoding reference.

If the data isn't that crazy extensive and you don't have ridiculously complicated relationships between your objects, writing everything out as a plist is probably your best option; it's very fast to execute and simple to implement in your code. Like you said, CoreData will probably be a lot of extra work to adapt your code to, and sqlite really is only good for storing data that's perfect to be stored in a relational database. Keep in mind that sqlite is also slower and uses more resources than working with binary plists.

Breed answered 18/5, 2009 at 2:44 Comment(0)
I
32

To serialize custom object you just need to conform to the NSCoding protocol. If your object extends NSObject all you need to do (I believe) is to implement these (example for person object):

// Encode an object for an archive
- (void)encodeWithCoder:(NSCoder *)coder
{
    [super encodeWithCoder:coder];
    [coder encodeObject:name forKey:@“Name”];
    [coder encodeInteger:age forKey:@“Age”];
}
// Decode an object from an archive
- (id)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    name = [[coder decodeObjectForKey:@“Name”] retain];
    age  = [coder decodeIntegerForKey:@“Age”];
}

NSArray and NSDictionary already implement methods for serialization. They will serialize all the objects that they hold (if objects implement NSCoder interface - they do if they extend NSObject). NSObject's encodeWithCoder and initWithCoder do nothing by default so unless you implement your own code in your classes nothing gets serialized.

If you have NSArray or NSDictionary of objects you can synchronize them using:

// Writing
- (BOOL)writeToFile:(NSString *)aPath atomically:(BOOL)flag;
- (BOOL)writeToURL:(NSURL *)aURL atomically:(BOOL)flag;
// Reading
- (id)initWithContentsOfFile:(NSString *)aPath;
- (id)initWithContentsOfURL:(NSURL *)aURL;
Incisor answered 18/5, 2009 at 3:37 Comment(3)
name is object of NSString type so you want to retain if you want to use it, age is only primitive integerIncisor
You can not use writeToFile, writeToURL unless the objects in the NSArray are of type NSString, NSData, NSArray, or NSDictionary. It will always return NO if you try to use these methods on an NSArray with any other object type.Triage
@Triage are you talking about NSArray full of other object types which all implement NSCoding protocol? Because that's what I explained above. Otherwise, not sure, it's 3 years old answer, stuff might have changed, please post your answer ppl will upvote if it's better solution.Incisor
B
14

You do this in the same way you'd do it on Mac OS X: your POCOs must conform to the NSCoding protocol. See here for a conceptual reference, and here for the NSCoding reference.

If the data isn't that crazy extensive and you don't have ridiculously complicated relationships between your objects, writing everything out as a plist is probably your best option; it's very fast to execute and simple to implement in your code. Like you said, CoreData will probably be a lot of extra work to adapt your code to, and sqlite really is only good for storing data that's perfect to be stored in a relational database. Keep in mind that sqlite is also slower and uses more resources than working with binary plists.

Breed answered 18/5, 2009 at 2:44 Comment(0)
P
0

NSCoder is the standard Cocoa idiom for serialization.

Pinkham answered 18/5, 2009 at 2:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.