Swift 4.0中归档第三方SDK自定义对象方案探究
可行!两种方案实现SDK模型存入UserDefaults
当然可以实现!虽然你没法修改SDK内部的Customer类代码,但我们可以借助Swift的扩展特性,通过归档/反归档或者字典映射的方式,把这个对象存入UserDefaults并读取。下面给你两种实用的方案:
方案一:利用NSCoding扩展实现归档存储
因为Customer继承自NSObject,我们可以给它扩展遵循NSCoding协议,实现归档和反归档的逻辑,这样就能把对象转成Data类型存入UserDefaults(UserDefaults支持存储Data)。
首先给Customer添加NSCoding扩展:
extension Customer: NSCoding { func encode(with coder: NSCoder) { // 编码每个属性 coder.encode(name, forKey: "name") coder.encode(age, forKey: "age") coder.encode(address, forKey: "address") // 注意:如果SDK的`Address`类也需要存储,你需要给它添加同样的NSCoding扩展 } required init?(coder: NSCoder) { super.init() // 解码每个属性 name = coder.decodeObject(forKey: "name") as? String age = coder.decodeInteger(forKey: "age") address = coder.decodeObject(forKey: "address") as? Address } }
然后是存储和读取的代码:
// 存储Customer对象 let customer = Customer() customer.name = "John Doe" customer.age = 30 // 假设你已经初始化了address属性... let encodedData = NSKeyedArchiver.archivedData(withRootObject: customer) UserDefaults.standard.set(encodedData, forKey: "SavedCustomer") // 读取Customer对象 if let savedData = UserDefaults.standard.data(forKey: "SavedCustomer"), let savedCustomer = NSKeyedUnarchiver.unarchiveObject(with: savedData) as? Customer { // 成功读取,使用savedCustomer print("读取到用户:\(savedCustomer.name ?? "未知"),年龄:\(savedCustomer.age ?? 0)") }
方案二:转字典映射存储(更灵活)
如果不想用归档,或者Address类无法通过NSCoding扩展处理,你可以把Customer对象转成字典存储,读取时再从字典还原成对象。
先给Customer添加字典转换的扩展:
extension Customer { // 将对象转成字典 func toDictionary() -> [String: Any] { var dict = [String: Any]() dict["name"] = name dict["age"] = age // 把Address也转成字典(需要给Address添加同样的扩展) dict["address"] = address?.toDictionary() return dict } // 从字典初始化对象 convenience init?(dictionary: [String: Any]) { self.init() name = dictionary["name"] as? String age = dictionary["age"] as? Int // 还原Address对象 if let addressDict = dictionary["address"] as? [String: Any] { address = Address(dictionary: addressDict) } } } // 给SDK的Address类添加对应的字典转换扩展(假设Address有street、city属性) extension Address { func toDictionary() -> [String: Any] { var dict = [String: Any]() dict["street"] = self.street dict["city"] = self.city return dict } convenience init?(dictionary: [String: Any]) { self.init() street = dictionary["street"] as? String city = dictionary["city"] as? String } }
然后是存储和读取的代码:
// 存储Customer对象 let customer = Customer() customer.name = "Jane Smith" customer.age = 28 // 初始化address属性... UserDefaults.standard.set(customer.toDictionary(), forKey: "SavedCustomerDict") // 读取Customer对象 if let customerDict = UserDefaults.standard.dictionary(forKey: "SavedCustomerDict"), let savedCustomer = Customer(dictionary: customerDict) { // 成功读取,使用savedCustomer }
注意事项
- 如果
Address类也是SDK内部的,必须给它添加对应的扩展(无论是NSCoding还是字典转换),否则无法完整存储和还原对象。 UserDefaults适合存储轻量级数据,如果你的Customer对象包含大量数据或者频繁读写,建议考虑使用Core Data或文件归档等更适合的存储方式。
内容的提问来源于stack exchange,提问作者Sazzad Hissain Khan
相关产品推荐
相关产品推荐

