Sam Soffes

Archiving Objective-C Objects with NSCoding

Posted in cocoa, iphone, mac, nscoding, objective-c, and tutorial

For the seasoned Cocoa developer, this is a piece of cake. For newer developers, this can be a real pain, especially if you don't know what you're looking for. I get this question a decent amount, so I figured I'd put a quick guide together.

The Problem

You can't put just any object in a plist. This mainly gets people when they want to put something into NSUserDefaults and get an error (because NSUserDefaults archives to a plist under the hood).

Plists only support the core types: NSString, NSNumber, NSDate, NSData, NSArray, NSDictionary (and their CF buddies thanks to the toll-free bridge). The key here is NSData. You can convert any object to NSData with the NSCoding protocol.

The Solution

There are two things you have to do: implement NSCoding and then use the archiver and unarchiver.

Implementing NSCoding

Say you have an object that looks like this:

Pretty simple, right?

Now, all you have to do to implement NSCoding is the following:

Pretty simple. All I did was add the <NSCoding> protocol delectation in the header file and initWithCoder: and encodeWithCoder: in the implementation. You use these methods to tell NSCoder how to encode your object into data. Notice how two of the variables are objects and one was a BOOL. You have to use different methods for non-objects. The NSCoder documentation has the full list.

Remember, that you can use NSCoder to archive your object however whatever you want. It doesn't have to just be all of the instance variables in your object, although that's what you'll do 90% of the time.

Using the Archiver and Unarchiver

This part is also really easy. Let's say you have an array of notes that you want to put into NSUserDefaults, here's the code:

Unarchiving is just as easy:

Updated iPhone JSON Benchmarks

Posted in benchmarks, cocoa, development, iphone, and json

I wrote a post awhile ago about JSON benchmarks. I was telling a friend he should use JSON Framework based on my old benchmark post. He asked if I had run them again recently, so I figured I'd run them again.

I updated my test app and added a new library called YAJL based on a C library. My results were very similar to before. This time I tested it on an iPad and iPod Touch.

16GB 1st Gen iPad running iOS 3.2

8GB 3rd Gen iPod Touch running iOS 3.1.3

Results

On both devices, they ranked Apple JSON, YAJL, JSON Framework, and TouchJSON. You can read the detailed results on GitHub.

In conclusion, it looks like YAJL is the new one to use. Again, feel free to check out my code on GitHub.

Archiving NSManagedObject with NSCoding

Posted in cocoa, core-data, and development

Several of the apps I have been working on lately have been using Core Data. Core Data is pretty sweet. So far, I really like it.

I needed to persist an array of NSManagedObjects to NSUserDefaults to persist the state of the application between launches. Obviously, I could have done this with another attribute on the Core Data entity, but this approach seemed a lot simpler. I was surprised that NSManagedObject didn't conform to NSCoding. I guess that makes sense because if you store any custom types in your entity, it wouldn't know how to archive them. In my case, (and I would assume most others) I didn't want to archive the entire object since it was already store in Core Data. I just needed to store the object ID.

This was actually really easy. See:

I always add + (id)sharedAppDelegate to my application delegate to save some typing:

Pretty simple right? Then you can do something like this to archive your objects:

Unarchiving is also super easy: