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
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - 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.