- 更新日: 2015年9月26日
- Swift & iOS
NSUserDefaultsにプロパティで値を保存・取得するSwiftラッパークラス
iOS 開発において NSUserDefaults(User Defaults)を使うと、簡単にデータを永続化して保存できます。Key/Value 方式で任意のオブジェクトの保存・読み込みが可能です。
— 環境 —
Swift 1.2
Xcode 6.3.2
NSUserDefaults 使い方の基本
NSUserDefaults を素のままで使う方法は以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 |
// NSUserDefaults のインスタンス取得 let ud = NSUserDefaults.standardUserDefaults() // キーを指定してオブジェクトを保存 ud.setObject("Swift Taro", forKey: "name") ud.synchronize() // キーを指定してオブジェクトを読み込み let name: String = ud.objectForKey("name") as! String // => "Swift Taro" // デフォルト値の設定 ud.registerDefaults(["name": "Swift Taro"]) |
上述のように、NSUserDefaults は簡単に扱うことができます。
特筆するとしたら、デフォルト値を NSUserDefaults#registerDefaults() メソッドに [ key: value ] のディクショナリを渡すことで設定できます。key が存在しない時にのみ、value をデフォルト値として初期化して設定してくれるので便利です。
NSUserDefaults にプロパティでアクセスするラッパー
簡単に扱える NSUserDefaults なのですが、アプリケーションの設定値などは、色んなコントローラーから取得したり、また設定画面などから変更したりするので、もっと簡単にプロパティ形式で取得・保存できるようにしたかった。理想としては NSUserDefaults に対して、以下のような感じで設定を保存したり取得できたら楽だな〜と。
1 2 3 4 5 6 |
// NSUserDefaults に保存 AppSetting.name = "Ruby Ichiro" AppSetting.age = 30 // NSUserDefaults の値を取得 AppSetting.name // => "Ruby Ichiro" AppSetting.age // => 30 |
Swift のコードでこれを実現するために、NSUserDefaults のラッパークラスとして、設定値を操作する AppSetting クラスを作りました。クラス変数としてのコンピューティッドプロパティ(Computed Property)を使う方法で実装してみたところ、上手く動作した。コードは以下の通り。
AppSetting.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
import Foundation class AppSetting { static let ud = NSUserDefaults.standardUserDefaults() // set default settings here private struct Default { static let name: String = "Swift Taro" static let age: Int = 20 } // computed properties as class variables class var name: String { get { ud.registerDefaults(["name": Default.name]) return ud.objectForKey("name") as! String } set(newValue) { ud.setObject(newValue, forKey: "name") ud.synchronize() } } class var age: Int { get { ud.registerDefaults(["age": Default.age]) return ud.objectForKey("age") as! Int } set(newValue) { ud.setObject(newValue, forKey: "age") ud.synchronize() } } } |
Computed Property の get でキーが存在しなかった時のためにデフォルト値を設定するようにしています。その後、キーを指定して値を取得。また、set でキーを指定して値を保存するようにしています。
以下、Playground での実行結果。
1 2 3 4 5 6 7 8 9 |
// デフォルト値を取得 AppSetting.name // => "Swift Taro" AppSetting.age // => 20 // 設定値を変更 AppSetting.name = "Ruby Ichiro" AppSetting.age = 30 // 変更された値を取得 AppSetting.name // => "Ruby Ichiro" AppSetting.age // => 30 |
これで NSUserDefaults を使ったアプリのグローバルな設定値などの取得・保存が、ものすごく簡単に行えるようになりました。任意のコントローラーの箇所で、AppSetting を通して設定値を取得・保存できます。懸念は Swift のバージョンアップでコードが動かなくなる可能性があることですかね。試行錯誤して書いたコードですので、まずい箇所があったら教えて下さい。
本当は Computed Property でプロパティ名を文字列で評価して、Ruby でいう Module#define_method や Object#send を使ったメタプログラミングのように書きたかったのですが、現状の私の Swift 力では無理でした。それができればコード量がぐっと減らせるのですけど。そもそも Swift はメタプログラミングできるんでしょうか…それすら知りません。
あとクラス(class)や構造体(struct)のプロパティ一覧を取得したいとも考えたのですが、これも Swift でのやり方が分からなかった。プロパティ一覧が取得できれば、ライブラリ化できるかな〜と思いまして。Swift でのメタプログラミングをちょっと調べてみようと思います。
- – 参考リンク –
- Swiftでクラス変数を作る方法 | Swift入門
- Swift ストアドプロパティ(Stored Property) コンピューテッド・プロパティ(Computed Property) – Codable Tech Blog
- [Swift]【NSUserDefaultsの基本的な使い方】表示、格納、削除。 – Qiita
- Swift & iOS の関連記事
- WKWebView/UIWebViewでウェブページが真っ白
- Unityのインストールと初期設定
- WKWebView/UIWebViewでNavigation Barの下にウェブページが隠れるのを回避
- SwiftでArray(配列)などをシャッフル
- Navigation Controllerで画面遷移させるSwiftコード
- Swiftでタップ/スワイプのイベント処理実装・UITapGestureRecognizerとUISwipeGestureRecognizer
- UIPageViewController画面下部のUIPageControlを非表示にする
- Swiftのバージョン確認・REPL実行
- Xcode7.0アップデートで遭遇した課題2つ
- 正規のXcodeかどうかチェック(XcodeGhostマルウェア騒動)
- 初回公開日: 2015年7月10日
Leave Your Message!