はじめに
-
NSUserDefaults
の扱いを簡単にしたい -
NSUserDefaults.standardDefaults()
って毎回書きたくない - キーを文字列リテラルで指定するのが嫌だ(タイポもあるし..)
などなどの不満から、NSUserDefaultsを扱う方法についていろいろ調べてみて試行錯誤した結果を残しておきます。
タイトルに「幾つか」と書いていますが、2つだけです
良い方法をご存知の方、ご教授ください。
1. enum
でキーを定義する
上記の記事を参考にさせていただきenum
を使ってNSUserDefaults
を使う方法を考えてみました。
ほぼほぼ上記の記事通りですが、キーに対応する値の型を明確にしたかったので、型を分けるためのenum
を入れ子にして入れてみました。
enum UserDefaults {
// Bool型の値を持つキーをcaseで定義
enum BoolValue: String {
case SomeFlag
func set(value: Bool) {
NSUserDefaults.standardUserDefaults().setBool(value, forKey: self.rawValue)
NSUserDefaults.standardUserDefaults().synchronize()
}
func get() -> Bool {
return NSUserDefaults.standardUserDefaults().boolForKey(self.rawValue)
}
}
// Int型の値を持つキーをcaseで定義
enum IntValue: String {
case UserID
func set(value: Int) {
NSUserDefaults.standardUserDefaults().setInteger(value, forKey: self.rawValue)
NSUserDefaults.standardUserDefaults().synchronize()
}
func get() -> Int {
return NSUserDefaults.standardUserDefaults().integerForKey(self.rawValue)
}
}
// String型の値を持つキーをcaseで定義
enum StringValue: String {
// ...
}
// 略...
}
使用時
UserDefaults.IntValue.UserID.set(1)
let userId = UserDefaults.IntValue.UserID.get() // 1
キーに対してどの型の値を入れるかは明確になった一方、
定義の段階においては、型ごとにgetメソッドとsetメソッドを作っているので、少々面倒ではあります。
また、使用時でもenum
のネストが深い分、「.」つなぎが多くなってしまうという点ではちょっと使いづらくなってしまった感じがあります。
2. struct
のプロパティとしてキーを定義する
2つ目ですが、こちらに関しては下記のライブラリを参考にしました。
https://github.com/radex/SwiftyUserDefaults
(そのままそのライブラリ使えよっていうのはいったん置いといて )
struct UserDefaultsKeys {
// ここにキーを定義していく
static var hasLoginKey = DefaultsKey<Bool>("someFlag")
static var userID = DefaultsKey<Int>("userID")
}
struct DefaultsKey<ValueType> {
let key: String
init(_ key: String) {
self.key = key
}
}
extension NSUserDefaults {
subscript(key: DefaultsKey<Bool>) -> Bool {
get {
return boolForKey(key.key)
}
set {
setBool(newValue, forKey: key.key)
synchronize()
}
}
subscript(key: DefaultsKey<Int>) -> Int {
get {
return integerForKey(key.key)
}
set {
setInteger(newValue, forKey: key.key)
synchronize()
}
}
subscript(key: DefaultsKey<String>) -> String {
// ...
}
// 略...
}
使用時
let UserDefaults = NSUserDefaults.standardUserDefaults()
UserDefaults[UserDefaultsKeys.userID] = 1
let userId = UserDefaults[UserDefaultsKeys.userID]
こちらも型ごとにsubscriptを書いてgetterとsetterを実装していますが、
subscriptでアクセスできる分、直感的に値のget, setを行いやすいというのはいいですね。
また、DefaultsKey
構造体でジェネリクスを用いて様々な型を受けられるようにし、NSDefaultsの拡張でその型に対応するsubscriptを作るというのは勉強になります。
最後に
ほとんど自分で考えたというものではないので記事にするのもおこがましいのですが、、
enum
やsubscript
, ジェネリクスの活用などは今回色々と考えてみて大変勉強になりました。