Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
解码JSON数组或字典错误_Json_Swift_Decode - Fatal编程技术网

解码JSON数组或字典错误

解码JSON数组或字典错误,json,swift,decode,Json,Swift,Decode,这是我第一次尝试Codable/Decodable,我想解码一个JSON。我正在尝试访问事件数组中的“名称”和“描述”键。下面是JSON的一个片段,我在代码中遇到了这个错误 “应解码字典,但找到了数组。” 下面是我如何解码的-(注意-“description”还没有出现,因为我在使用events数组访问name&description时遇到了一个问题 struct Eventbrite: Decodable { private enum CodingKeys : String, Coding

这是我第一次尝试Codable/Decodable,我想解码一个JSON。我正在尝试访问事件数组中的“名称”和“描述”键。下面是JSON的一个片段,我在代码中遇到了这个错误

“应解码字典,但找到了数组。”

下面是我如何解码的-(注意-“description”还没有出现,因为我在使用events数组访问name&description时遇到了一个问题

struct Eventbrite: Decodable {

 private enum CodingKeys : String, CodingKey { case events = "events",  name = "name"}
    let events: [String:[String]]
    let name: [String:[String]]

}

   URLSession.shared.dataTask(with: url) { (data, response, error) in

        guard let data = data else {return}

        do {

        let eventbriteData = try JSONDecoder().decode(Eventbrite.self, from: data)


            print(eventbriteData.name)

名称
显然不在
分页
事件
(请注意
{}
)的范围内,它是一个常规的
[String:String]
字典,可以解码为另一个结构

解码(由于
说明
不完整,我遗漏了它),您不需要
编码键

struct Eventbrite: Decodable {
    let events: [Event]
}

struct Event: Decodable {
    let name: Name
    // let description: [String:String]
}

struct Name : Decodable {
    let text, html : String
}

名称
显然不在
分页
事件
(请注意
{}
)的范围内,它是一个常规的
[String:String]
字典,可以解码为另一个结构

解码(由于
说明
不完整,我遗漏了它),您不需要
编码键

struct Eventbrite: Decodable {
    let events: [Event]
}

struct Event: Decodable {
    let name: Name
    // let description: [String:String]
}

struct Name : Decodable {
    let text, html : String
}

所以Decodable实际上是非常聪明的,因为你真的不需要编写任何代码来自己解码。你只需要确保你匹配JSON结构(并且使结构也符合任何嵌套对象的Decodable)换句话说,与其将变量作为字典,不如将它们作为自己的可解码结构

例如:

struct EventBrite: Decodable {
    let pagination: Pagination
    let events: [Event]
}

struct Pagination: Decodable {
    let page_number: Int
    let page_size: Int
    let continuation: String
    let has_more_items: Bool
}

struct Event: Decodable { 
     let name: EventName
     let description: EventDescription
}

struct EventName: Decodable {
    let name: String
    let html: String
}
等等

这里重要的另一点是,如果不能保证返回键或属性(比如说,
EventName
并不总是具有从服务器返回的html值,您可以轻松地将该值标记为可选值。例如:

struct EventName: Decodable {
    let name: String
    let html: String?
}
另一方面,您实际上弄乱了字典类型声明。您会注意到,
事件
实际上是类型
[String:[String:String]]
,因为键是字符串,值似乎总是字典。名称是
[String:String]
。这与您最初的问题不同

当值可能与分页不同时,您可能希望执行类似于
[String:Any]
的操作,因此请注意这一点

然而我认为我建议的方法比让属性成为字典要好。首先,你不必担心声明字典的类型(你在上面犯了一些小错误)。但更重要的是,当每个字典都成为自己的清晰定义结构时,您不必担心记住或查找键。点语法/自动完成将自动告诉您可以有什么!(并且当您的值类型为
Any
AnyObject
!)时,不会强制转换)


我曾经对性能进行过基准测试,并测量过结构的效率,其效率是类的数百万倍。仅供参考。

好的,所以Decodable实际上非常聪明,因为你真的不需要编写任何代码来自己解码。你只需要做一些确保匹配JSON结构(并使结构也符合任何嵌套对象的可解码结构)。换句话说,与其将变量作为字典,不如使它们成为自己的可解码结构

例如:

struct EventBrite: Decodable {
    let pagination: Pagination
    let events: [Event]
}

struct Pagination: Decodable {
    let page_number: Int
    let page_size: Int
    let continuation: String
    let has_more_items: Bool
}

struct Event: Decodable { 
     let name: EventName
     let description: EventDescription
}

struct EventName: Decodable {
    let name: String
    let html: String
}
等等

这里重要的另一点是,如果不能保证返回键或属性(比如说,
EventName
并不总是具有从服务器返回的html值,您可以轻松地将该值标记为可选值。例如:

struct EventName: Decodable {
    let name: String
    let html: String?
}
另一方面,您实际上弄乱了字典类型声明。您会注意到,
事件
实际上是类型
[String:[String:String]]
,因为键是字符串,值似乎总是字典。名称是
[String:String]
。这与您最初的问题不同

当值可能与分页不同时,您可能希望执行类似于
[String:Any]
的操作,因此请注意这一点

然而我认为我建议的方法比让属性成为字典要好。首先,你不必担心声明字典的类型(你在上面犯了一些小错误)。但更重要的是,当每个字典都成为自己的清晰定义结构时,您不必担心记住或查找键。点语法/自动完成将自动告诉您可以有什么!(并且当您的值类型为
Any
AnyObject
!)时,不会强制转换)


我曾经对性能进行过基准测试,并测量过结构的效率,其效率是类的数百万倍。仅供参考。

感谢您的回复。您帮助我理解了结构以及如何正确解码。我这方面的一个简单新手错误是ch现在更清楚了。谢谢!谢谢你的回复。你帮助我理解了它的结构以及如何正确解码。我这方面的一个简单的新手错误,现在更清楚了。谢谢!谢谢你的解释。你进一步帮助我理解了这个概念!嘿,回顾这篇评论,我现在对w实际上有点困惑你最后的建议是什么?你能澄清一下所有编辑的意思吗?谢谢你,所以我的建议是,不要在任何地方使用字典作为属性,而是创建一个新的结构,该结构也符合Decodable。这样就不必做
event[“name”]
你可以做
event.name
。在我看来,它更容易使用,而且还有解码的魔力