对象序列化作为常用的数据本地化方法之一,经常用来保存用户信息等,其序列化方法也很简单,只需要实现NSCoding协议,实现其协议方法即可!
但当我们的对象属性比较多的时候,就会显现出一些不方便了,但这在Swift 4.0中就变得相当方便了。
Swift 3.0 之前的方式
Swift 3.0之前的方式,和OC中的序列化方式相同,先实现NSCoding协议,然后实现其协议方法,在其协议方法中分别对各个属性进行encode和decode操作,以保存用户信息为例:
需要注意:这里的对象需要继承自NSObject;
// 使用NSCoding进行序列化
class LQUser: NSObject, NSCoding {
var name: String = ""
var age: Int32 = 0
var psw: String = ""
static var user: LQUser {
let ud = UserDefaults.standard
guard let data = ud.data(forKey: "lqUser_savedData") else {
// 如果获取失败则重新创建一个返回
return LQUser()
}
guard let us = NSKeyedUnarchiver.unarchiveObject(with: data) as? LQUser else { return LQUser() }
return us
}
func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: "name")
aCoder.encode(age, forKey: "age")
aCoder.encode(psw, forKey: "psw")
}
private override init() {
super.init()
}
required init?(coder aDecoder: NSCoder) {
if let rs = aDecoder.decodeObject(forKey: "name") as? String {
name = rs
}
if let rs = aDecoder.decodeObject(forKey: "psw") as? String {
psw = rs
}
age = aDecoder.decodeInt32(forKey: "age")
}
func saved() {
let us = UserDefaults.standard
let data = NSKeyedArchiver.archivedData(withRootObject: self)
us.set(data, forKey: "lqUser_savedData")
us.synchronize()
}
}
以上代码也比简单,都能看明白,使用的时候不用调用其初始化方法,只需要直接调用其类属性user即可:
let user = LQUser.user
user.age = 28
user.name = "流火绯瞳"
user.psw = "123456"
user.saved()
在给各个属性赋值之后,调用其保存方法saved()即可!
取值的时候,也是调用user:
let user = LQUser.user
print(user.name)
看上去也挺简单的,是的,当属性少的时候,是不复杂;但是,如果你要序列化的一个对象包含N多个属性,你就要对这N多个属性分别写一遍encode与decode,难度不大,简单谈不上,只是一些重复的操作,且不易维护!
Swift 4.0新的协议 Codable
在Swift 4.0中新出的协议 Codable 就可以避免上面的方式中的问题,而且使用也十分简单:
// swift 4.0 新协议 Codable
class LQUser: NSObject, Codable {
var name: String = ""
var age: Int = 0
var psw = ""
static var user: LQUser {
let ud = UserDefaults.standard
guard let data = ud.data(forKey: "lqUser_savedData") else {
// 如果获取失败则重新创建一个返回
return LQUser()
}
guard let us = try? JSONDecoder().decode(self, from: data) else {
return LQUser()
}
return us
}
private override init() {
super.init()
}
func saved() {
if let data = try? JSONEncoder().encode(self) {
let us = UserDefaults.standard
us.set(data, forKey: "lqUser_savedData")
us.synchronize()
}
}
}
这里使用的是 JSONEncoder / JSONDecoder 进行编解码,也可以选择使用其他的方式,但是不能使用NSKeyedArchiver / NSKeyedUnarchiver。
使用的时候同第一种:
// 存
let user = LQUser.user
user.age = 28
user.name = "流火绯瞳"
user.psw = "123456"
user.saved()
取:
let user = LQUser.user
print(user.name)
另外,这里的类也是继承自NSObject的,也可以不继承:
class LQUser: Codable {
var name: String = ""
var age: Int = 0
var psw = ""
static var user: LQUser {
let ud = UserDefaults.standard
guard let data = ud.data(forKey: "lqUser_savedData") else {
// 如果获取失败则重新创建一个返回
return LQUser()
}
guard let us = try? JSONDecoder().decode(self, from: data) else {
return LQUser()
}
return us
}
private init() {
}
func saved() {
if let data = try? JSONEncoder().encode(self) {
let us = UserDefaults.standard
us.set(data, forKey: "lqUser_savedData")
us.synchronize()
}
}
}
甚至也可以是结构体:
// swift 4.0 新协议 Codable
struct LQUser: Codable {
var name: String = ""
var age: Int = 0
var psw = ""
static var user: LQUser {
let ud = UserDefaults.standard
guard let data = ud.data(forKey: "lqUser_savedData") else {
// 如果获取失败则重新创建一个返回
return LQUser()
}
guard let us = try? JSONDecoder().decode(self, from: data) else {
return LQUser()
}
return us
}
private init() {
}
func saved() {
if let data = try? JSONEncoder().encode(self) {
let us = UserDefaults.standard
us.set(data, forKey: "lqUser_savedData")
us.synchronize()
}
}
}
可以发现其便利性,不仅可存储的类型多了,主要的还是不用对每个属性去分别encode与decode。