しめ鯖日記

swift, iPhoneアプリ開発, ruby on rails等のTipsや入門記事書いてます

NSUserDefaultsにプロパティー形式でアクセスできるLKUserDefaultsを試してみた

LKUserDefaultsという超絶便利なライブラリを試したのでその事を書いてみます。

github.com

NSUserDefaultsの使い方

まずはLKUserDefaultsを使わずにNSUserDefaultsへアクセスする方法を書きます。
NSUserDefaultsの値の取得・保存・デフォルト値のセットは通常下のように行います。

// 取得
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSInteger intValue = [userDefaults integerForKey:@"myKey"];

// 保存
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setInteger:100 forKey:@"myKey"];
[userDefaults synchronize]; 

// デフォルト値のセット
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];  // 取得
[userDefaults registerDefaults:@{
    @"myKey": @(1)
}];

NSUserDefaultsの問題

簡単に値をセットできるNSUserDefaultsなんですが下のような問題があります。

キーを文字列指定するので補完が効かないしミスが起こる

見出しの通りでNSUserDefaultsの値の操作には@"myKey"のように文字列キーを渡す必要があります。
これは補完も効かないしスペルミスによる思わぬ不具合も招くので宜しくないです。

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSInteger intValue = [userDefaults integerForKey:@"myKey"];

下のようにマクロでkeyを定義すれば少し楽になるのですがマクロが長くなりがちですしあまりスマートな感じがしません。

#define USER_DEFAULTS_KEY_MY_KEY @"myKey"

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSInteger intValue = [userDefaults integerForKey:USER_DEFAULTS_KEY_MY_KEY];

synchronizeのセットを忘れる

NSUserDefaultsを使っていると「[userDefaults synchronize];を忘れてなぜか値が保存されない。」という現象があります。
これは下のようにセッターメソッドを定義すれば良いのですが、一々メソッドを定義するのが辛いです。

- (void)setMyValue:(int)value {
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    [userDefaults setInteger:value forKey:@"myKey"];
    [userDefaults synchronize];
}

LKUserDefaultsを使った場合

LKUserDefaultsを使うと下のようにプロパティー定義するだけで取得・保存ができるようになります。

@interface MyUserDefaults : LKUserDefaults
@property (strong, nonatomic) NSString* myValue;
@end
MyUserDefaults *userDefaults = [MyUserDefaults sharedInstance];
userDefaults.name = @"Hoge"; 

デフォルト値のセットも下のように簡単に書くことができます。

@implementation MyUserDefaults

- (void)registerDefaults {
    self.myValue = @"defaultValue";
}

@end

LKUserDefaultsの使い方

LKUserDefaultsCocoaPodsにも対応しているのでPodfileに下のように書いてpod installすれば導入完了です。

pod "LKUserDefaults", :git => 'https://github.com/lakesoft/LKUserDefaults.git'

あとは先ほど書いたようにLKUserDefaultsを継承したクラスを作り、そこにプロパティーを定義すれば完了です。

@interface MyUserDefaults : LKUserDefaults
@property (strong, nonatomic) NSString* myValue;
@end

Swiftへの対応状況

Swiftでは条件によっては動かす事ができます。
objective-cで作ったMyUserDefaultsSwiftから呼ぶ事はできるのですが、Swiftで作ったMyUserDefaultsSwiftで呼ぶと落ちます。
具体的には下のようなパターンがダメです。

class MyUserDefaults: LKUserDefaults {
    var myValue: String = ""
}

MyUserDefaults().myValue = "A"

上のMyUserDefaultsObjective-cから使う事は可能でした。

まとめ

LKUserDefaultsNSUserDefaultsを理想的な形で扱えて最高のライブラリでした!