環境:swift2.1
NSUserDefaults
にオブジェクトのまま保存したかったが、保存できるオブジェクトはNSArray
, NSDictionary
, NSString
, NSNumber
, NSDate
,NSData
に限られていた。
調べたところ、オブジェクトをNSData
に変換できることがわかった。
NSData
にできればNSUserDefaults
にも保存できる。
実装方法
- 対象のオブジェクトに
NSCoding
プロトコルのデコードメソッドinit?(coder aDecoder: NSCoder)
とエンコードメソッドencodeWithCoder(aCoder: NSCoder)
を実装する - 保存時は
NSKeyedArchiver.archivedDataWithRootObject:
でオブジェクトをNSData
に変換 - 読み込み時は
NSKeyedUnarchiver.unarchiveObjectWithData:
でNSData
からオブジェクトに変換
以下サンプルコード
struct UserDefaultsKey { static let User = "user" } struct SerializedKey { static let UserId = "userId" static let Uuid = "uuid" static let NickName = "nickName" } class User: NSObject, NSCoding { var userId: Int var uuid: String var nickName: String? init(userId: Int, uuid: String, nickName: String? = nil) { self.userId = userId self.uuid = uuid self.nickName = nickName } required init?(coder aDecoder: NSCoder) { self.userId = aDecoder.decodeObjectForKey(SerializedKey.UserId) as? Int ?? 0 self.uuid = aDecoder.decodeObjectForKey(SerializedKey.Uuid) as? String ?? "" self.nickName = aDecoder.decodeObjectForKey(SerializedKey.NickName) as? String } func encodeWithCoder(aCoder: NSCoder) { aCoder.encodeObject(self.userId, forKey: SerializedKey.UserId) aCoder.encodeObject(self.uuid, forKey: SerializedKey.Uuid) aCoder.encodeObject(self.nickName, forKey: SerializedKey.NickName) } } class UserService { static let sharedInstance = UserService() private let userDefaults = NSUserDefaults.standardUserDefaults() func register(userId userId: Int, uuid: String, nickName: String? = nil) { let archivedObject = NSKeyedArchiver.archivedDataWithRootObject(User(userId: userId, uuid: uuid, nickName: nickName)) self.userDefaults.setObject(archivedObject, forKey: UserDefaultsKey.User) self.userDefaults.synchronize() } var registeredUser: User? { guard let unarchivedObject = self.userDefaults.objectForKey(UserDefaultsKey.User) as? NSData, let user = NSKeyedUnarchiver.unarchiveObjectWithData(unarchivedObject) as? User else { return nil } return user } }
使用時
// 保存 UserService.sharedInstance.register(userId: 1, uuid: "xxxxx") // 取得 let user = UserService.sharedInstance.registeredUser
この方法でNSData
にすればシリアライズ・デシリアライズできるのでNSUserDefaults
ではなくファイルとしても保存できる。
参考:
iOS でオブジェクトをシリアライズしてファイルに保存する方法 - A Day In The Life
http://glassonion.hatenablog.com/entry/20110904/1315145330