swift - 通用快速对象序列化?
问题描述
是否有通用的方法来序列化/反序列化 iOS 对象?我正在使用以下代码,并且我调用的系统函数在 iOS 12 中已弃用:
func object(forKey:String) -> Any? {
if let data = get(BLOB_COL, forKey) {
return NSKeyedUnarchiver.unarchiveObject(with: data as! Data)
}
return nil
}
func set(_ object:Any, forKey: String) {
let data = NSKeyedArchiver.archivedData(withRootObject: object)
updateOrInsert(forKey, BLOB_COL, data)
}
看起来这些函数的新版本需要对象类的知识,以及用于取消归档不同集合类型的不同签名......有没有一种简单的方法来处理这个问题?
解决方案
如果你想使用 NSKeyedArchiver/NSKeyedUnarchiver:
归档更改时:
NSKeyedArchiver.archivedData...
至
NSKeyedArchiver.archivedData(withRootObject: object, requiringSecureCoding: false)
当取消归档更改时
NSKeyedUnarchiver.unarchiveObject...
至
NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data)
可编码协议通用方法
如果您想使用 Codable 进行编码和解码(序列化),您Data
可以扩展 Encodable 协议并创建一个方法来编码符合它的任何对象:
extension Encodable {
func data(using encoder: JSONEncoder = JSONEncoder()) throws -> Data { try encoder.encode(self) }
}
要解码编码数据,您可以扩展Data
并创建一个通用方法来解码任何符合 Decodable 的对象:
extension Data {
func object<T: Decodable>(using decoder: JSONDecoder = JSONDecoder()) throws -> T {
try decoder.decode(T.self, from: self)
}
// you can also create a string property to convert the JSON data to String
var string: String? { String(data: self, encoding: .utf8) }
}
用法:
struct Person: Codable {
let name: String
let age: Int
}
do {
// encoding
let person = Person(name: "Joe", age: 10)
var people = [Person]()
people.append(person)
let data = try people.data()
print(data.string ?? "") // [{"name":"Joe","age":10}]
// decoding
let loadedPeople: [Person] = try data.object()
loadedPeople.forEach({print( $0.name, $0.age)}) // Joe 10
} catch {
print(error)
}
推荐阅读
- javascript - 如何在按钮单击 Reactjs 上增加项目?
- python - 反转链表改变原来的链表
- r - R Shiny - 如何在会话开始时检查查询字符串
- java - 尝试使用资源(PreparedStatements)
- react-native - 在 react-native < 0.60 中处理 UIWebView(和 Apple Store 警告)的另一种方法
- python - 作为另一个函数的参数的函数
- haskell - 类型构造函数后面的值的异构列表 (HList) 的类型
- flutter - Flutter - 存储经过身份验证的用户详细信息
- typescript - TypeScript:强制转换整个类类型
- php - HTML表单发布方法和url的PHP cURL问题