NSUserDefaults
の代わりにRealmを使ってみると良いかもしれない
iOSアプリ内に何らかの設定値を保存する場合、基本的にNSUserDefaults
に保存しているかと思います。
ただしNSUserDefaults
は、[String:AnyObject]
でアクセスしなければならず、Swiftでは結構扱いにくいです(ラッパークラスをうまく設計できていれば問題は起きないのかもしれませんが)。
それから色々な場所から色々なkeyで値が保存されるため、気がついたらどこに何が入っているか分からないということにも起きがちちゃないのではないでしょうか。
いろいろ考えてみたのですが、Realmを使うと"アプリの構造"を扱いやすくなるのではないのか、と思いました。こちらの記事でも同様のことが述べられています。
ということでRealmSwiftで簡単なサンプルを書いてみました。
サンプルコード解説
シンプルにユーザーの状態(ゲスト状態かログイン状態か)と、起動した日時を記録しようと思います。
サンプルではユーザーの状態をenum
で定義しています。
enum UserState: String {
case Guest, Login
}
Realmではenum
はプロパティとして扱えないので、enum
のrawValue
でString
にしてプロパティに代入します。
そしてObject
を継承してAppState
を定義します。
class AppState: Object {
dynamic var state: String = UserState.Guest.rawValue
dynamic var launchDateTime: NSDate = NSDate()
}
以下のようなSingletonのRealmのラッパークラスを作成します。
final class AppStateManager {
static let sharedInstance = AppStateManager()
private init() {}
private var realm: Realm {
guard let realm = try? Realm() else {
fatalError()
}
return realm
}
func update(userState: UserState ,launchDateTime: NSDate) {
let state = AppState()
state.state = userState.rawValue
state.launchDateTime = launchDateTime
do {
try self.realm.write({ [weak self] () -> Void in
guard let stateManager = self else {
return
}
stateManager.realm.add(state)
})
} catch {
print("could not write")
}
}
}
こんな感じでアプリ起動時にRealmへ保存を行います。
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
AppStateManager.sharedInstance.update(UserState.Guest, launchDateTime: NSDate())
return true
}
AppDelegate
のoptional func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool
で呼び出すことを想定しています。
まとめ
UserDefaultsにRealmを使ってみることについて考えてみましたが、実際に使う際には結構リスクが高位のだろうなとも感じました。リスクを考慮した上で、許容できるのであれば、個人的には良い解決方法になるのではないかなと思います。
以下に個人的に感じたメリット、デメリットについてまとめてみました。
メリット
-
AppState
などの状態をモデルとして定義することで、どんな情報が保存されているのかが構造化されて分かりやすい -
NSUserDefaults
から取り出す際のキャストが不要 - 条件を指定して保存したデータの絞り込みがしやすい
デメリット
- Realmが1.0を迎えていない現段階ではリスクになりそう
- 既存のアプリに途中から入れることは難しそう
- マイグレーション怖い
補足
僕はあまりDB周りは得意ではないので、もっと色々なことがメリット、デメリット考えられるかと思うので、ご指摘いただけると嬉しいです。