NSUserDefaults best practices

Following previous post and observing in many projects how NSUserDefaults settings are handled I have decided to write this NSUserDefaults best practices.

If you look for information about how to set/get any value in the default storage you will get this:

NSString *valueToSave = @"someValue";
[[NSUserDefaults standardUserDefaults] setObject:valueToSave forKey:@"preferenceName"];
[[NSUserDefaults standardUserDefaults] synchronize];

and for getting the value:

NSString *savedValue = [[NSUserDefaults standardUserDefaults]

Easy, Is not it? The problem appears when there are many attributes deal with with the sets and gets scattered along the code and you want set break points for trapping when this attribute is being accessed.


What I propose is to wrap this functionality in a single class that concentrates all the attributes that we want to get/set from the default storage system.

This is the declaration .h:

#import <Foundation/Foundation.h>

@interface ManagerSettings : NSObject

+(ManagerSettings*) sharedInstance;

@property (nonatomic, assign) int attributeName;


Its implementation .m:

#import "ManagerSettings.h"

@implementation ManagerSettings

    static ManagerSettings *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[ManagerSettings alloc] init];
        // Do any other initialisation stuff here
    return sharedInstance;

#pragma mark - Properties

static NSString *const kAttributeName = @"attributeName";

- (int)attributeName
    return [[[NSUserDefaults standardUserDefaults] objectForKey:kAttributeName] intValue];

- (void)setAttributeName:(int)value
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:[NSNumber numberWithInt:value] forKey:kAttributeName];
    [defaults synchronize];


The class is implemented as a singleton and for each attribute are overwritten set (and get) methods. In that way in a unique place the attribute is set (and get) into (from) the storage system.

And its usage:

    [ManagerSettings sharedInstance].attributeName=5;
    NSLog(@"%d",[ManagerSettings sharedInstance].attributeName);

The access to the attribute is more clean and in a unique class file we have all the system storage functionality concentrated. You can download the project used for writing this post here.





Leave a Reply

Your email address will not be published. Required fields are marked *

two × three =