swiftでデータ永続化と画面間の変数共有
Swiftで、AppDelegateで変数を共有しつつNSUserDefaultsでデータの永続化をテストしてみた。
共有する変数がInt型とかだとラベル用のString型に変換するのが意外と面倒なので一度ローカル変数に入れ直すと楽だった。あとは、ディスクデータの削除をしてもディスクデータの初読み込みでも、nilが返って来ないのが意外だった。
今回のプロジェクトは、Tabbed Applicationで開始。github.com
データの永続化
FirstViewController.swift
・データの保存と削除
@IBAction func saveBtn(sender: AnyObject) { // AppDelegateのインスタンスを取得 let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate // NSUserDefaults型でディスク書き込み let defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults() defaults.setInteger(appDelegate.point, forKey: "UserPoint") let success = defaults.synchronize() if success { println("保存に成功") } } @IBAction func clearBtn(sender: AnyObject) { // AppDelegateのインスタンスを取得 let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate // キーを元にディスクから削除 let defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults() defaults.removeObjectForKey("UserPoint") let success = defaults.synchronize() if success { println("削除に成功") } else { println("削除するデータなし") return } // 表示中のデータリセット appDelegate.point = 0 self.viewDidAppear(false) }
・データの読み出し
override func viewDidLoad() { super.viewDidLoad() println("1st_viewDidLoaded") // AppDelegateのインスタンスを取得 let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate // ディスクから読み出し let defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults() let wrapSavePoint: Int? = defaults.integerForKey("UserPoint") // アンラッピング if let savePoint: Int = wrapSavePoint { println("データ読み出し成功unwrapped:\(savePoint)") appDelegate.point = savePoint } else { println("データなしwrapped:\(wrapSavePoint)") } }
画面間の変数共有
viewDidLoadはコントローラビュー読み込み1度目しか呼ばれないので、画面遷移で共有データを逐一読み出すためには、viewDidAppearを使う。
AppDelegate.swift
class AppDelegate: UIResponder, UIApplicationDelegate { // 画面間で共有する変数pointの宣言と初期化 var point: Int = 0 〜省略〜 }
FirstViewController.swift
class FirstViewController: UIViewController { @IBOutlet weak var firstViewLabel: UILabel! @IBAction func firstViewBtn(sender: AnyObject) { // AppDelegateのインスタンスを取得 let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate // appDelegateの変数を操作 ++appDelegate.point // ラベル表示,ラベル用にString型へ変換 let tmpPoint: Int = appDelegate.point firstViewLabel.text = "[\(String(tmpPoint))]" } 〜省略〜 override func viewDidAppear(animated: Bool) { // AppDelegateのインスタンスを取得 let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate // ラベル表示,ラベル用にString型へ変換 let tmpPoint: Int = appDelegate.point firstViewLabel.text = "[\(String(tmpPoint))]" }
SecondViewController.swift
class SecondViewController: UIViewController { @IBOutlet weak var secondViewLabel: UILabel! @IBAction func secondViewBtn(sender: AnyObject) { // AppDelegateのインスタンスを取得 let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate // appDelegateの変数を操作 ++appDelegate.point // ラベル表示,ラベル用にString型へ変換 let tmpPoint: Int = appDelegate.point secondViewLabel.text = "[\(String(tmpPoint))]" } 〜省略〜 override func viewDidAppear(animated: Bool) { // AppDelegateのインスタンスを取得 let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate // ラベル表示,ラベル用にString型へ変換 let tmpPoint: Int = appDelegate.point secondViewLabel.text = "[\(String(tmpPoint))]" }