本文为CocoaChina网友desty投稿
概述:
UserDefaults:Key-Value持久化的方案,适合用来保存配置数据,简单的用户信息,或者一些状态数据(大批量数据还是要考虑使用DB)
Archiver:对象类型无法直接进行持久化,需要对象遵循序列化的协议。
UserDefaults使用:
UserDefaults.standard.set(value, forKey: String)
Archiver使用:
Object-C / Swift3中需要实现NSCoding协议:
class Person: NSObject, NSCoding {
public func encode(with aCoder: NSCoder) {
// 需根据属性自己实现
}
public required init?(coder aDecoder: NSCoder) {
// 需根据属性自己实现
}
}
let personData = NSKeyedArchiver.archivedData(withRootObject: Person())下面是通过OC的runtime机制实现的动态实现NSCoding协议,想要某个类支持NSCoding协议,只需要继承CodingSupport即可。
open class CodingSupport: NSObject, NSCoding {
public func encode(with aCoder: NSCoder) {
var count: UInt32 = 0
let ivars = class_copyIvarList(self.classForCoder, &count)
for i in 0.. Swift4中实现简单很多,只需要支持Codable协议:
class Person: Codable {
}
let encoder = JSONEncoder()
let personData = try? encoder.encode(Person()) 上面介绍了些关于UserDefaults和Archiver的用法,但这并不是本文的主题,本文的主题是将两者融合用在实际项目中,
1. 解决UserDefaults在存储数据时出现的代码分散,不易管理
2. 在多个用户间切换时,数据持久化的问题。
案例1:用户A信息需要存储,推荐做法
class User: Codable {
var name = "default name"
var mask = "defalut mask"
var age = 0
var gendar = 0
var level = 0
var status = 0
}
// 存储
let user = User()
let encoder = JSONEncoder()
let encoded = try? encoder.encode(user)
UserDefaults.standard.set(encoded, forKey: "UserA")
UserDefaults.standard.synchronize()
// 获取
let infoData = UserDefaults.standard.object(forKey: "UserA")
guard let info = infoData as? Data else { return nil }
let decoder = JSONDecoder()
let decoded = try? decoder.decode(T.self, from: info) 假如此时切换到了用户B,并存储B的相关信息,我们需要在UserDefaults时设置是使用不同的key。
关于这些操作的封装有一个框架PieceStore,github地址: https://github.com/ZeroFengLee/PieceStore,这个框架对Model数据的存储做了很好的封装。