我的数据结构如下所示。 “人类”是键的字典,其值是人类的字典:
"humans" : {
"abc123" : {
"name" : "Vince",
"pets" : [ {
"animal" : "dog",
"name" : "Clifford"
}, {
"animal" : "fish",
"name" : "Nemo"
} ]
},
"xyz789" : {
"name" : "Jack"
}
}
所以我的Swift结构看起来像这样:
struct Human: Codable {
var name: String!
var pets: [Pet]?
}
struct Pet: Codable {
var name: String!
var animal: Animal!
}
enum Animal: String, Codable {
case cat
case dog
case fish
}
我尝试这样解码(使用CodableFirebase库):
let human = try FirebaseDecoder().decode([Human].self, from: value)
但是在尝试对具有某些对象数组的对象进行编码时,出现以下错误:
typeMismatch(Swift.Array,Swift.DecodingError.Context(codingPath: [],debugDescription:“不是数组”,底层错误:nil))
如何将字典中的值正确编码为自定义Swift对象的数组?
答案 0 :(得分:1)
有几个问题:
首先,您犯了一个常见错误:您忽略了JSON的根对象,该对象是具有一个键humans
的字典。那是试图告诉你的错误。
struct Root : Codable {
let humans : [Human]
}
let human = try FirebaseDecoder().decode(Root.self, from: value)
但是即使添加根结构也不起作用,因为键humans
的值是一个字典,请注意{}
struct Root : Codable {
let humans : [String:Human]
}
最后,永不,永不,永不将可解码的结构成员声明为隐式未包装的可选变量,它们是非可选的(是的,代码编译时没有感叹号)或常规的可选(?
)
struct Human: Codable {
var name: String
var pets: [Pet]?
}
struct Pet: Codable {
var name: String
var animal: Animal
}
enum Animal: String, Codable {
case cat, dog, fish
}
如果要在Human
结构中使用Root
数组而不是字典,则必须编写自定义初始化程序
struct Root : Codable{
let humans : [Human]
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let humanData = try container.decode([String:Human].self, forKey: .humans)
humans = Array(humanData.values)
}
}