Rikh Rikh - 10 months ago 96
iOS Question

Storing custom objects as NSDictionary vs NSData

I was going through some tutorials regarding storing custom objects in NSUserDefaults. I can't figure out which is the better approach and/or benefits regarding storing your model after converting it back to

and storing the dictionary vs using
to store the object in
. As per my understanding you will have to set the
methods which will enable you set the values for various keys and basically convert everything to
. Converting the model back to
will also follow the same steps.

So what are the benefits of using one approach over the other or if one approach may cause something to break anywhere?

will do something like:

- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:self.test forKey:@"string"];
[encoder encodeObject:self.surname forKey:@"surname"];

And converting model back to

-(NSDictionary *)dictionaryWithModel:(Model *)model{

NSDictionary *dictionary = @{
@"dict":[model.innerModel dictionaryWithModel:model.innerModel],

return dictionary;

Basically which of the would be better when storing object in

Answer Source

Here is my answer on another similar question.

You can set object like this:

NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:savingbean];
[currentDefaults setObject:data forKey:@"DATA"];
[currentDefaults synchronize];

and for get object like this:

NSData *data = [currentDefaults objectForKey:@"DATA"];
SavingBean *token = [NSKeyedUnarchiver unarchiveObjectWithData:data];

For Custom class you have to edit this methods in you bean class:

- (void)encodeWithCoder:(NSCoder *)encoder
    [encoder encodeObject:self.userName==nil?@"":self.userName forKey: @"userName"];
    [encoder encodeObject:self.passWord==nil?@"":self.passWord forKey: @"passWord"];

-(id)initWithCoder:(NSCoder *)decoder
    self = [super init];
        self.userName = [decoder decodeObjectForKey: @"userName"];
        self.passWord = [decoder decodeObjectForKey: @"passWord"];
    return self;

Here is most voted similar answer. You can also get good stuff from there.

You can also use JSON Accelerator to create bean class. This is very simple and powerful tool.


The NSUserDefaults class provides convenience methods for accessing common types such as floats, doubles, integers, Booleans, and URLs. A default object must be a property list, that is, an instance of (or for collections a combination of instances of): NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. If you want to store any other type of object, you should typically archive it to create an instance of NSData.

Values returned from NSUserDefaults are immutable, even if you set a mutable object as the value. For example, if you set a mutable string as the value for "MyStringDefault", the string you later retrieve using stringForKey: will be immutable.

Note: The user defaults system, which you programmatically access through the NSUserDefaults class, uses property lists to store objects representing user preferences. This limitation would seem to exclude many kinds of objects, such as NSColor and NSFont objects, from the user default system. But if objects conform to the NSCoding protocol they can be archived to NSData objects, which are property list–compatible objects. For information on how to do this, see ““Storing NSColor in User Defaults”“; although this article focuses on NSColor objects, the procedure can be applied to any object that can be archived.



When defining your app’s preferences, it is better to use simple values and data types whenever possible. The preferences system is built around property-list data types such as strings, numbers, and dates. Although you can use an NSData object to store arbitrary objects in preferences, doing so is not recommended in most cases.

Storing objects persistently means that your app has to decode that object at some point. In the case of preferences, a stored object means decoding the object every time you access the preference. It also means that a newer version of your app has to ensure that it is able to decode objects created and written to disk using an earlier version of your app, which is potentially error prone.

A better approach for preferences is to store simple strings and values and use them to create the objects your app needs. Storing simple values means that your app can always access the value. The only thing that changes from release to release is the interpretation of the simple value and the objects your app creates in response.