将具有不同字典的Plist转换为结构体

3
我有一个plist,它是一个字典的数组(根为数组)。每个字典肯定有两个值:nameicon作为Strings。但有些字典有更多的键/值,有些则没有。
我正在尝试使用以下结构读取数组:
struct Config: Decodable {
    private enum CodingKeys: String, CodingKey {
        case name, icon
    }

    let name: String
    let icon: String
}



func functionsStruct() -> Config {
    let url = Bundle.main.url(forResource: "FunctionsList", withExtension: "plist")!
    let data = try! Data(contentsOf: url)
    let decoder = PropertyListDecoder()
    return try! decoder.decode(Config.self, from: data)
}
  1. 我阅读了一本字典,学习了如何阅读字典数组和如何设置结构。

  2. 如何解决某些字典具有其他字典不具备的键的问题?


你可以将这些键变成可选的。例如 let someProperty: String? - Mike Taverne
谢谢,问题是如何保存字典数组而不是数组。我想不出来。 - Curnelious
2
解码[Config].self不起作用? - Cristik
2个回答

4

针对您的第一个问题:

我阅读了一本字典,学习如何读取字典数组以及如何设置结构。

func functionsStruct() -> [Config] {
            let url = Bundle.main.url(forResource: "FunctionsList", withExtension: "plist")!
            let data = try! Data(contentsOf: url)
            let decoder = PropertyListDecoder()
            return try! decoder.decode([Config].self, from: data)
        }

就这么简单!!!

1
如果你想要一个字典数组,那么你不需要创建自己的 Codable 类。数组和字典已经实现了 Codable
只需执行以下操作:
func functionsStruct() -> [[String: String]] {
    let url = Bundle.main.url(forResource: "FunctionsList", withExtension: "plist")!
    let data = try! Data(contentsOf: url)
    let decoder = PropertyListDecoder()
    return try! decoder.decode([[String: String]].self, from: data)
}

如果字典中包含除字符串以外的值,您可以使用[[String: Any]]

然后,您可以像这样访问您的nameicon

let dicts = functionsStruct()
print(dicts[0]["name"])

然而,我不明白为什么你坚持使用字典。我强烈推荐你坚持使用Codable结构体。你可以将可选的键变成可选项:

struct Config: Decodable {
    let name: String
    let icon: String
    let optionalKey1: String?
    let optionalKey2: String?
}

如果键在属性列表中不存在,它们的值将为零。

您需要解码一个Config数组,而不仅仅是像您之前所做的那样解码Config

return try! decoder.decode([Config].self, from: data)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接