繁体   English   中英

如何在Swift中编码Codables字典?

How to encode a dictionary of Codables in Swift?

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我在Swift中有一个[String: Codable]字典,我想保存到用户默认值中,但是我在努力做到这一点。

我尝试使用将其转换为Data

try! JSONSerialization.data(withJSONObject: dictionary, options: .init(rawValue: 0))

但这会导致崩溃(“ JSON写入(_SwiftValue)中的类型无效”)

我试过使用JSONEncoder

JSONEncoder().encode(dictionary)

但这不会编译(“无法推断通用参数T”)。

当然,我可以将所有的Codables手动转换为[String:Any],然后将其写入用户默认值,但是由于Codable的全部目的是使“解码”和“编码”变得容易,所以我不确定为什么上述两种解决方案都是不可能(尤其是第二个)?

范例

为了重现性,您可以在Playground中使用以下代码:

import Foundation

struct A: Codable {}
struct B: Codable {}

let dict = [ "a": A(), "b": B() ] as [String : Codable]
let data = try JSONEncoder().encode(dict)
2 个回复

作为一般约束, CodableAny是不可编码的。 使用结构而不是字典:

struct A: Codable {
    let a = 0
}
struct B: Codable {
    let b = "hi"
}
struct C: Codable {
    let a: A
    let b: B
}

let d = C(a: A(), b: B())
let data = try JSONEncoder().encode(d)

UserDefaults有一种保存[String:Any]字典的方法:

let myDictionary: [String: Any] = ["a": "one", "b": 2]
UserDefaults.standard.set(myDictionary, forKey: "key")
let retrievedDictionary: [String: Any] = UserDefaults.standard.dictionary(forKey: "key")!
print(retrievedDictionary)      // prints ["a": one, "b": 2]

但是,如果字典是要保存到UserDefaults的对象的属性,则需要为该对象实现Codable协议。 我知道的最简单的方法是使用JSONSerialization将字典转换为Data对象。 以下代码对我有用:

class MyObject: Codable {

    let dictionary: [String: Any]

    init(dictionary: [String: Any]) {
        self.dictionary = dictionary
    }

    enum CodingKeys: String, CodingKey {
        case dictionary
    }

    public required init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        if values.contains(.dictionary), let jsonData = try? values.decode(Data.self, forKey: .dictionary) {
            dictionary = (try? JSONSerialization.jsonObject(with: jsonData) as? [String: Any]) ??  [String: Any]()
        } else {
            dictionary = [String: Any]()
        }
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        if !dictionary.isEmpty, let jsonData = try? JSONSerialization.data(withJSONObject: dictionary) {
            try container.encode(jsonData, forKey: .dictionary)
        }
    }
}

要从UserDefaults保存和检索MyObject ,可以执行以下操作:

extension UserDefaults {

    func set(_ value: MyObject, forKey defaultName: String) {
        guard let data = try? PropertyListEncoder().encode(value) else { return }
        set(data, forKey: defaultName)
    }

    func myObject(forKey defaultName: String) -> MyObject? {
        guard let data = data(forKey: defaultName) else { return nil }
        return try? PropertyListDecoder().decode(MyObject.self, from: data)
    }
}
1 在Swift中从数组和字典编码为JSON

我试图从我在应用程序内部快速创建的数组创建JSON文件。 我需要将“数组”编码为JSON,因为我之前创建了字典和数组,而我只是将它们组合到该数组中。 在我的代码中,我有: 我先将orderArray放入dict中,然后再将dict放入order中。 如果我打印的输出是正确的 ...

2 Swift 4中的可编码JSON字典

在@matt的帮助下。 我能够解决这个问题,下面的完成代码是任何在不久的将来会遇到类似问题的人的。 给定下面的JSON 我正在尝试使用此代码将Dictionary中的数组访问到表中。 所以我做了一个结构。 以下是我的Structfile的内容。 这是我的主要View Co ...

3 如何在Swift 4.1中将混合值类型字典编码为JSON

下面的代码适用于Xcode 9.2(Swift 4.0),但在Xcode 9.3(Swift 4.1)中出现错误。 我一直试图使该词典[String: Encodable] ,并使用typealias既字典类型,具有相同的结果。 Swift不允许您在泛型调用中指定类型,因此会产生编译器 ...

4 如何在Swift中对字典排序

如何在Swift中对字典排序? 我的字典声明: 我的目标:我需要字典中的元素按从高到低的值(颜色出现的时间)排序。 我尝试过的事情:我已经在网上进行了一些研究,而且我知道Swift中的Dictionary不提供排序功能。 所以我写了下面的代码: 我得到的输出是:“最 ...

8 如何在 Swift 中的字典中插入数组

我正在 Swift 中创建一个绘图应用程序,可以在画布上为 HTML 重绘。 只是一个原型。 我需要的是将这些数据以JSON格式传输到我的数据库中。 我在数组和字典中组织了所有内容。 我怎样才能生成这样的东西: 使用Arrays and Dicionaries (and / or Struct ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM