You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:32:08