Edited at

NSUserDefaultsのwrapperを書くのが面倒になったとき

More than 5 years have passed since last update.


背景

NSUserDefaultsを直接使用するとkeyがわからなくなったり、typoでバグったりといろいろ大変です。そのためgetter/setterのmethodを定義することで補完を効かせたりdefaultの値を設定できるようにすることがあるかと思います。

iOS - NSUserDefaultsを使うときはWrapして使うと便利 - Qiita

しかし、毎回以下の様な感じで値ごとにgetter/setterを記述するのは大変です。

+ (NSString *)hoge {

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults registerDefaults:@{@"hoge" : @"default"}];
return [userDefaults stringForKey:@"hoge"];
}

+ (void)setHoge:(NSString *)string {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:string forKey:@"hoge"];
}

そこで今回はGVUserDefaultsを使用して退屈なコードとはオサラバします。


使い方

まずはpodをinstallします。


Podfile

  pod "GVUserDefaults"


次にGVUserDefaultsのカテゴリーを定義し、その中に使いたい値をpropertyとして記述します。


GVUserDefaults+Properties.h

#import "GVUserDefaults.h"


@interface GVUserDefaults (Properties)
@property (nonatomic, weak) NSString *name;
@property (nonatomic) NSInteger age;
@end


GVUserDefaults+Properties.m

@implementation GVUserDefaults (Properties)

@dynamic name;
@dynamic age;
@end


上記の定義だけで、property経由で値をget/setすることができるようになります。

//getter

NSString *string = [GVUserDefaults standardUserDefaults].name;
//setter
[GVUserDefaults standardUserDefaults].name = @"myname";

初期値を設定したい場合はsetupDefaultsを定義します。

- (NSDictionary *)setupDefaults {

return @{
@"name": @"anonymous",
@"age": @20
};
}

このままだとUserDefaultsに登録されるkeyの名前はpropertyのと同じになってしまい、もし他にもNSUserDefaultsを使用していると衝突する恐れがあります。transformKeyを定義することで、keyにprefixをつけましょう。

なお、ここでprefixを付けても、前述のsetupDefaultsにprefixをつけるなどの変更は必要ありません。GVUserDefaultsが良きに計らってくれます。

- (NSString *)transformKey:(NSString *)key {

// 先頭を大文字に
key = [key stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[[key substringToIndex:1] uppercaseString]];
return [NSString stringWithFormat:@"NSUserDefault%@", key];
}


さいごに

冗長なコードをGVUserDefaultsに任せることで肝心のlogicに集中することができます。また、今回定義したgetter/setterに加え、それらを使う高次のmethodを定義すれば、userDefaultsを使用する側としてもわかりやすいインタフェースを用意できるかと思います。

GVUserDefaultsはobjc/runtime.hを使用しており黒魔術感は有りますが、もし不安に思うならGVUserDefaults.mを見てみると良いでしょう。コードは250行程度で、とてもわかり易いものとなっていますので、理解はさほど難しく無いと思います。


参考