せでぃのブログ

ブログ初心者おいどんのどうでもいい愚痴やどうでもいい愚痴やどうでもいいマメ知識などを披露するチラシの裏です。

swiftでデータ永続化と画面間の変数共有

 Swiftで、AppDelegateで変数を共有しつつNSUserDefaultsでデータの永続化をテストしてみた。
 共有する変数がInt型とかだとラベル用のString型に変換するのが意外と面倒なので一度ローカル変数に入れ直すと楽だった。あとは、ディスクデータの削除をしてもディスクデータの初読み込みでも、nilが返って来ないのが意外だった。
 今回のプロジェクトは、Tabbed Applicationで開始。github.com
f:id:Sediment:20150507105406p:plainf:id:Sediment:20150507105414p:plain

データの永続化

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))]"
    }