【Swift】NSUserDefaultsの使い方。アプリの設定情報を保存する。(Swift 2.1、XCode 7.2)
NSUserDefaultsとは
本記事ではNSUserDefaultsの使い方について説明する。
NSUserDefaultsとは、アプリで入力、編集したデータを端末に保存する機能である。
アプリ起動中に入力したデータはメモリに一時保持されているだけなので、保存せずにアプリを終了するとメモリのデータが消えるとともに入力データも消える。なので、再起動しても前回の入力データを見ることはできない。
アプリを使いやすくするために入力データを保存しておきたい。そんなときに利用されるのがNSUserDefaultsである。
NSUserDefaultsを使ってデータを保存すると、一旦メモリ上にデータが置かれ、アプリの動きとは非同期で保存ファイル(plistファイル)への出力が行われる。
そして、アプリ再起動時にplistファイルのデータが自動でメモリに展開される。これにより、前回の状態を維持したままアプリを利用できるということだ。
NSUserDefaultsはplistファイルのデータをすべてメモリ上に展開するため、限られたメモリ領域で大量データを扱うと領域が逼迫する危険がある。
また、Swiftの辞書と同じように「キーと値」をセットにデータを保持するので検索が実装しづらい。ゆえに、NSUserDefaultsは大量のデータを扱うには不向きであり、設定情報などの軽量データを扱うのに適した機能である。
データを保存する機能には他にCore DataやiCloudがあるので、大量データを保存する場合はそちらを利用するのが良い。
NSUserDefaultsを使ってみる
テキストフィールドに入力した文字列をNSUserDefaultsを使って保存し、アプリ再起動時に再び参照できるものを実装してみよう。
以降の手順を開始する前のXcodeプロジェクトをGitHubに置いたので、試してみる人はご利用されたし。
⇒「テスト用プロジェクト」
事前準備では、テキストフィールドに入力した文字列をラベルに表示するようにしておいた。保存処理は実装していないので、アプリを再起動するとラベルに表示したデータは初期値に戻る。
ViewController.swiftを以下のコードに変更する。
アプリ起動時に文字列が保存されているかを確認し、保存されている場合はラベルに表示している。
テキストフィールドの入力終了時に、ラベルに設定された文字列を保存している。文字列を確実に保存するためにsynchronizeメソッドを使ってplistファイルへの出力と同期をとっている。
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 35 36 37 38 39 40 41 42 43 44 45 46 |
// // ViewController.swift // import UIKit class ViewController: UIViewController,UITextFieldDelegate{ @IBOutlet weak var testLabel: UILabel! @IBOutlet weak var testTextField: UITextField! let userDefaults = NSUserDefaults.standardUserDefaults() //最初からあるメソッド override func viewDidLoad() { super.viewDidLoad() //デリゲート先を自分に設定する testTextField.delegate = self //文字列が保存されている場合はラベルに文字列を設定する。 if let labelText = userDefaults.stringForKey("labelText") { testLabel.text = labelText } } //Returnキー押下時の呼び出しメソッド func textFieldShouldReturn(textField:UITextField) -> Bool { //キーボードをしまう self.view.endEditing(true) //テキストフィールドの文字列をラベルに設定する。 testLabel.text = testTextField.text //ラベルの文字列を保存する。 userDefaults.setObject(testLabel.text, forKey:"labelText") //plistファイルへの出力と同期する。 userDefaults.synchronize() return false } } |
以下は実際のプレイ動画。前回入力した文字列が再起動時に表示されるようになった。
保存できるデータ型
NSUserDefaultsを使って保存できるデータ型はStringに限らず、様々な型を保存できる。
以下のコードはNSUserDefaultsで使えるデータ型を用いて、データの保存、読込みを試したコード。
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
// // ViewController.swift // import UIKit class ViewController: UIViewController,UITextFieldDelegate{ @IBOutlet weak var testLabel: UILabel! @IBOutlet weak var testTextField: UITextField! let userDefaults = NSUserDefaults.standardUserDefaults() //最初からあるメソッド override func viewDidLoad() { super.viewDidLoad() //Bool型のデータを保存、読込 userDefaults.setObject(true, forKey: "testBool") let result1 = userDefaults.boolForKey("testBool") //Int型のデータを保存、読込 userDefaults.setInteger(7, forKey: "testInt") let result2 = userDefaults.integerForKey("testInt") //Float型のデータを保存、読込 userDefaults.setFloat(1.23, forKey: "testFloat") let result3 = userDefaults.floatForKey("testFloat") //Double型のデータを保存、読込 userDefaults.setDouble(4.56, forKey: "testDouble") let result4 = userDefaults.doubleForKey("testDouble") //String型のデータを保存、読込 userDefaults.setObject("テスト", forKey: "testString") let result5 = userDefaults.stringForKey("testString") //String型配列のデータを保存、読込 userDefaults.setObject(["値1","値2"], forKey: "testStringArray") let result6 = userDefaults.stringArrayForKey("testStringArray") //Dictionary型のデータを保存、読込 userDefaults.setObject(["キー":"値"], forKey: "testDictionary") let result7 = userDefaults.dictionaryForKey("testDictionary") //NSURL型のデータを保存、読込 userDefaults.setURL(NSURL(string: "http://www.test.co.jp"), forKey: "testURL") let result8 = userDefaults.URLForKey("testURL") //配列データを保存、読込 userDefaults.setObject([123,"テスト"], forKey: "testArray") let result9 = userDefaults.arrayForKey("testArray") //Object型のデータを保存、読込 userDefaults.setObject("テスト", forKey: "testObject") let result10 = userDefaults.objectForKey("testObject") //NSData型のデータを保存、読込 let str = "NSData型をテストします" let data = NSData(data: str.dataUsingEncoding(NSUTF8StringEncoding)!) userDefaults.setObject(data, forKey: "testNSData") let result11 = NSString(data:userDefaults.dataForKey("testNSData")!, encoding:NSUTF8StringEncoding) print("Bool:\(result1)") print("Int:\(result2)") print("Float:\(result3)") print("Double:\(result4)") print("String:\(result5!)") print("String配列:\(result6!)") print("Dictionary型:\(result7!)") print("NSURL型:\(result8!)") print("配列:\(result9!)") print("オブジェクト型:\(result10!)") print("NSData型:\(result11!)") } } |