NSUserDefaultsに自作クラスを保持(swift)

NSUserDefaultsでは保存可能なクラスが限られていてそのままでは自作クラスの保存が出来ない。
調べてみるとNSDataの変換を行う事で可能との事。
ただし、ほとんどの情報がObjective-Cによる記載だったので、swiftでの対応を簡単に記録。

こちらこちらを参考にさせてもらいました。


自作クラスに対して行う事
・NSObjectクラスの継承とNSCodingプロトコルの実装
・初期化処理で親init呼び出し
・encodeWithCoder(aCoder: NSCoder) の実装(シリアライズ処理)
・init(coder: NSCoder)の実装(デシリアライズ処理)

NSUserDefaults保存時に行う事
・NSKeyedUnarchiver.unarchiveObjectWithDataでアーカイブしNSDataに変換

NSUserDefaults取得時に行う事
・NSKeyedArchiver.archivedDataWithRootObjectでアンアーカイブして元に戻す


実装例)
環境:Xcode:7.2.1、swift:2.1.1

自作classのMyClass

import Foundation

class MyClass: NSObject,NSCoding{

var data1: Int = 0
var data2: Int = 0

override init() {
super.init()
}

//シリアライズ
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(data1, forKey: "data1_key")
aCoder.encodeObject(data2, forKey: "data2_key")
}

//デシリアライズ
required init(coder: NSCoder) {
self.score1 = coder.decodeObjectForKey("data1_key") as! Int
self.score2 = coder.decodeObjectForKey("data2_key") as! Int
}

//以下任意処理
func hoge(foo: Int){
data2 = data1
data1 = foo
}
}


保存・取得処理

//取得
let data: AnyObject! = NSUserDefaults.standardUserDefaults().objectForKey("my_class_key")
var myClass: MyClass
if data != nil {
//アンアーカイブし、元のオブジェクトに戻す
myClass = NSKeyedUnarchiver.unarchiveObjectWithData(data as! NSData) as! MyClass

} else {
//保存データがない場合は新規にオブジェクト作成
myClass = ScoreData()
}

//取得したオブジェクトの関数を実行
myClass.hoge(1)

//保存
//アーカイブしNSDataに変換
let sendNsData: NSData = NSKeyedArchiver.archivedDataWithRootObject(myClass)
NSUserDefaults.standardUserDefaults().setObject(sendNsData as AnyObject, forKey:"my_class_key")
NSUserDefaults.standardUserDefaults().synchronize()



単純な数字や文字以外をNSUserDefaultsで保存するなという話かも知れませんが、
データ量が多くない場合はどうしてもお手軽さに負けて・・・


スポンサーリンク

この記事へのコメント


この記事へのトラックバック