简体   繁体   English

如何从 Swift 中的 JSON 文件中读取混合类型的数组?

[英]How can I read in an array of mixed types from a JSON file in Swift?

I am currently trying to create a movie search app in Xcode and am having trouble reading in the JSON file from IMDB's API.我目前正在尝试在 Xcode 中创建电影搜索应用程序,并且无法从 IMDB 的 API 中读取 JSON 文件。

API Example: https://sg.media-imdb.com/suggests/h/h.json API 示例: https://sg.media-imdb.com/suggests/h/h.json

I can read in almost the entire file except for the image information ('i') which is stored as an array with a URL (string) and two optional ints for the dimensions.除了图像信息('i')之外,我几乎可以读取整个文件,它存储为一个数组,其中包含一个 URL (字符串)和两个可选的尺寸整数。

   struct Response: Codable {
        var v: Int
        var q: String
        var d: [item]
    }
    
    struct item: Codable {
        var l: String
        var id: String
        var s: String
        var i: ??
    }

No matter what type I enter for 'i' the parse fails.无论我为“i”输入什么类型,解析都会失败。 I can't create an array with mixed types so I am confused how to continue.我无法创建具有混合类型的数组,所以我很困惑如何继续。

Thanks谢谢

You need to do some custom decoding here.您需要在此处进行一些自定义解码。 You can use the nestedUnkeyedContainer method to get the coding container for the array, and decode the array elements one by one.可以使用nestedUnkeyedContainer方法获取数组的编码容器,对数组元素一一解码。

Here is how you would implement Decodable :以下是实现Decodable的方法:

struct Response: Decodable {
     let v: Int
     let q: String
     let d: [Item]
 }
 
struct Item: Decodable {
    let l: String
    let id: String
    let s: String
    let url: String
    let width: Int?
    let height: Int?
    
    enum CodingKeys: CodingKey {
        case l, id, s, i
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        l = try container.decode(String.self, forKey: .l)
        id = try container.decode(String.self, forKey: .id)
        s = try container.decode(String.self, forKey: .s)
        var nestedContainer = try container.nestedUnkeyedContainer(forKey: .i)
        url = try nestedContainer.decode(String.self)
        width = try nestedContainer.decodeIfPresent(Int.self)
        height = try nestedContainer.decodeIfPresent(Int.self)
    }
}

It doesn't seem like you need to conform to Encodable so I didn't include it, but the code should be similar if you ever need to.您似乎不需要遵守Encodable所以我没有包含它,但是如果您需要,代码应该是相似的。

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

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