ユーザーの設定情報などちょっとしたデータを保存しておきたい場合などにはUserDefaultsを使う事で簡単にデータ保存ができます。
Xcode 11.4
データの保存
iOSアプリでデータを保存するには幾つかの方法があります。
- UserDefaults
- keyとそれに対応するvalueで簡単に実装可能
- Core Data
- データをレコード形式で保存しデータが大量なケースに向いている
- KeyChain
- セキュアなエリアに保存して重要なデータ保存に使われる
これ以外にもiCloudのようにサーバー上にデータを保存する方法や、オープンソースのRealmなどがあります。
ここでは、簡単で少量のデータ保存を想定したUserDefaultsの実装を試して見ます。
UserDefaults
基本的にはKey, valueの形式でXMLファイルで保存されています。高速にそれを読み書きするために(実際は時間がかかる)アプリ起動時に読み込んでキャッシュに入れていたりします。
そのため時々XMLファイルとキャッシュの同期を取っておく必要があります。
UserDefaultsを使ったデータの読み書きの概要です。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// UserDefaults のインスタンス let userDefaults = UserDefaults.standard // デフォルト値 userDefaults.register(defaults: ["DataStore": "default"]) // Keyを指定して保存 userDefaults.set(str, forKey: "DataStore") // Keyを指定して読み込み let str: String = userDefaults.object(forKey: "DataStore") as! String // Key の値を削除 userDefaults.removeObject(forKey: "DataStore") |
サンプルコード
まとめたコード例です。
TextFieldに入力したStringをUserDefaultsで保存。アプリを再起動させた初期画面には保存したデータを読み出して表示しています。また「Clear」ボタンを押すとデータがクリアされ初期値が表示されます。
ViewController.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 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 |
import UIKit class ViewController: UIViewController, UITextFieldDelegate { @IBOutlet var textField:UITextField! @IBOutlet var label:UILabel! var testText:String = "default" // UserDefaults のインスタンス let userDefaults = UserDefaults.standard override func viewDidLoad() { super.viewDidLoad() // textFiel の情報を受け取るための delegate を設定 textField.delegate = self // デフォルト値 userDefaults.register(defaults: ["DataStore": "default"]) label.text = readData() } func textFieldShouldReturn(_ textField: UITextField) -> Bool{ testText = textField.text! label.text = testText // キーボードを閉じる textField.resignFirstResponder() saveData(str: testText) return true } func saveData(str: String){ // Keyを指定して保存 userDefaults.set(str, forKey: "DataStore") } func readData() -> String { // Keyを指定して読み込み let str: String = userDefaults.object(forKey: "DataStore") as! String return str } @IBAction func buttonTapped(_ sender : Any) { // Key の値を削除 userDefaults.removeObject(forKey: "DataStore") // Keyを指定して読み込み let str: String = userDefaults.object(forKey: "DataStore") as! String label.text = str } } |
これでLabel, TestField, Buttonをコードと紐付ければ出来上がりです。
サンプル動画
アプリに書き込んだ後で、アプリを終了させる動作がちょっと面倒です。基本的にはアプリは終了させないのがAppleの基本なので。その方がバッテリー消費がトータルで軽減されるということでしょう。
ただアプリが終了するという確たるものが欲しいのであえて終了させました。Foregroundから消しだだけでは待機状態なので
Ref:
UserDefaults – Foundation | Apple Developer Documentation