ios - Swift - 保存 [String : Any] to NSUserDefauls 的数组

标签 ios swift nsuserdefaults codable decodable

我发现这个扩展使用 Codable 保存到 NSUserDefaults 中

extension UserDefaults {
    func decode<T : Codable>(for type : T.Type, using key : String) -> T? {
        let defaults = UserDefaults.standard
        guard let data = defaults.object(forKey: key) as? Data else {return nil}
        let decodedObject = try? PropertyListDecoder().decode(type, from: data)
        return decodedObject
    }

    func encode<T : Codable>(for type : T, using key : String) {
        let defaults = UserDefaults.standard
        let encodedData = try? PropertyListEncoder().encode(type)
        defaults.set(encodedData, forKey: key)
        defaults.synchronize()
    }
}

但正如我所见,我有一个错误 Type 'OfflineRequest' does not conform to protocol 'Decodable' 看起来像因为 Any

我有下一个要保存的结构:

struct OfflineRequest: Codable {
    let url: String
    let params: [String: Any]
}

这个想法是持久存储由于任何连接问题而失败的请求堆栈(数组)。所以我有 Core Data 数据模型,并且在将其发送到服务器之前将其属性转换为 [String: Any]。但现在我想创建离线优先算法。因此,如果用户离线,我想持久存储 url 和参数,即 [String: Any]。在这种情况下如何正确处理不符合“可解码”协议(protocol)

最佳答案

您可以使用 JSONSerialization.data(withJSONObject: Any) 对字典进行编码,并使用 JSONSerialization.JSONObject(with: Data) 对其进行解码。你只需要确保你传递了一个有效的 json 对象(在本例中是一个字典),如果你传递一个类型如 Date 的字典,它将崩溃。像这样尝试:

struct OfflineRequest: Codable {
    let url: String
    let params: [String: Any]
}

extension OfflineRequest {
    init(from decoder: Decoder) throws {
        var container = try decoder.unkeyedContainer()
        url = try container.decode(String.self)
        params = try JSONSerialization.jsonObject(with: container.decode(Data.self)) as? [String:Any] ?? [:]
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.unkeyedContainer()
        try container.encode(url)
        try container.encode(JSONSerialization.data(withJSONObject: params))
    }
}

let test = [OfflineRequest(url: "http://www.google.com", params: ["a":"1","b":"test", "c":["d":"test"]])]

let data = try! JSONEncoder().encode(test)
let loaded = try! JSONDecoder().decode([OfflineRequest].self, from: data)
print(loaded) // [__lldb_expr_3.OfflineRequest(url: "http://www.google.com", params: ["b": test, "a": 1, "c": {\n    d = test;\n}])]\n"

关于ios - Swift - 保存 [String : Any] to NSUserDefauls 的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57270873/

相关文章:

ios - 保留关键字不会在 Xcode 4.6 ARC 项目中抛出编译器错误?

ios - 在标签中显示来自 firebase 身份验证的用户电子邮件

swift - 需要详细解释 Swift 中的 Memoize 实现(WWDC 14, session 404)

swift - 核心图形中的动画

ios - Swift 编译器警告 : Result of call to 'save(defaults:)' is unused

iphone - iOS 能够在模拟器上读取 plist 文件,但不能在设备上读取

ios - 在 View Controller 上添加导航栏

ios - UIView 子类,触摸事件

iphone - 如何重新启动 iDevice?

iphone - 如何在 NSURLRequest 中使用身份验证 token