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]
    stringForKey:@"preferenceName"];

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.

Proposal

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;

@end

Its implementation .m:

#import "ManagerSettings.h"

@implementation ManagerSettings


+(ManagerSettings*)sharedInstance
{
    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];
}

@end

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 =