NSUserDefaults using properties

Using properties to access data from NSUserDefaults is a million times better than using the verbose API. To do this you simply make a category on NSUserDefaults and then chuck in some boiler plate code to hook it all up.

It couldn't be simpler...

Defgen makes it simpler

Boiler plate is boring so why write it? Using Defgen we can have the computer write it for us. Supply a Defaultfile written in the super simple DSL and defgen will do the rest.

Features

This is firmly in the realms of Proof of Concept at the minute but.

  • Uses class prefix used in your Xcodeproj
  • Uses the OrganizationName in your Xcodeproj
  • Customizable boiler plate
  • No runtime tricks and all the NSUserDefault supported types are supported
  • Automatically updates your Xcodeproj

Usage

Step 1. Supply a Defaultfile

# ├── AwesomeApp/
#     ├── AwesomeApp/
#     ├── AwesomeApp.xcodeproj/
#     ├── Defaultfile           <----- Your Defaultfile

# Defaultfile
array      'cheatCodes'
bool       'firstUse'
data       'someData'
dictionary 'config'
float      'ratio'
integer    'year'
object     'mmmmmm'
string     'name'
double     'betterRatio'
url        'homepage'

The DSL should be pretty self explanatory call the type of the object followed by what you want to call it.

Step 2. Run Defgen

$ defgen

Step 3. Enjoy the generated boiler plate

Customisation

Sometimes you want to have a different getter so you can follow conventions like having a boolean isValid and setValid:, which sounds nicer than isValid and setIsValid:

Simple...

bool 'valid', :getter => 'isValid'

which generates

// NSUserDefaults+PASProperties.h

@property (nonatomic, assign, getter=pas_isValid) BOOL pas_valid;

// NSUserDefaults+PASProperties.m

- (BOOL)pas_isValid;
{
  return [self boolForKey:PASValid];
}

- (void)setPas_valid:(BOOL)isValid;
{
  [self setBool:isValid forKey:PASValid];
}

If you don't like my choice of using strong for object properties you can override this in the same way

array 'colours', :ownership => :weak

which generates

// NSUserDefaults+PASProperties.h

@property (nonatomic, weak) NSArray *pas_colours;

Advanced Customisation

If you don't like the supplied boiler plate then you can tweak it.

Step 1. Call generate the stubs

$ defgen stubs

This will generate the templates in your current project so that you can edit as much as you like

create  defgen/constant.erb
create  defgen/getter.erb
create  defgen/implementation.erb
create  defgen/interface.erb
create  defgen/property.erb
create  defgen/setter.erb

Example input/output/usage

Input

#Defaultfile

array 'aliases'

Output

//
//  NSUserDefaults+PASProperties.h
//  AwesomeApp
//
//  Created by Paul Samuels on 04/01/2013.
//  Copyright (c) 2013 Paul Samuels. All rights reserved.
// 
//  This is an autogenerated file any changes will be lost when running `defgen`
//

#import <Foundation/Foundation.h>

@interface NSUserDefaults (PASProperties)

@property (nonatomic, strong) NSArray *pas_aliases;

@end

//
//  NSUserDefaults+PASProperties.m
//  AwesomeApp
//
//  Created by Paul Samuels on 04/01/2013.
//  Copyright (c) 2013 Paul Samuels. All rights reserved.
// 
//  This is an autogenerated file any changes will be lost when running `defgen`
//

#import "NSUserDefaults+PASProperties.h"

NSString * const PASAliases = @"PASAliases";

@implementation NSUserDefaults (PASProperties)

- (NSArray *)pas_aliases;
{
  return [self arrayForKey:PASAliases];
}

- (void)setPas_aliases:(NSArray *)aliases;
{
  [self setObject:aliases forKey:PASAliases];
}

@end

Usage

#import "NSUserDefaults+PASProperties.h"

...

userDefaults.pas_aliases = @[ @1, @2 ];
NSLog(@"%@", userDefaults.pas_aliases);

Installation

$ gem install defgen

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Wish List

  • Dry runs to show what will be generated

Licence

Defgen is available under the MIT license. See the LICENSE file for more info.