Плист с разными словарями в структуру - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть plist, который является массивом словарей .(корень это массив).Каждый dic имеет 2 значения наверняка: name и icon как 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. как решить, что у некоторых диков есть ключи, которых у других нет?

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Для вашего первого вопроса:

Я читаю словарь, как читать массив словарей и как настроить структуру.

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)
        }

Кактак просто !!!

0 голосов
/ 14 ноября 2018

Если вам нужен массив словарей, вам не нужно создавать собственный класс 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]], если словарь содержит значения, отличные от строк.

И тогда вы можете получить доступ к своим name и icon следующим образом:

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)
...