Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.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
Swift 可编码错误-应解码字典<;字符串,任意>;但是找到了一个数组_Swift_Codable - Fatal编程技术网

Swift 可编码错误-应解码字典<;字符串,任意>;但是找到了一个数组

Swift 可编码错误-应解码字典<;字符串,任意>;但是找到了一个数组,swift,codable,Swift,Codable,我试图在codable的帮助下解码JSON- 然而,当我这样做的时候,我得到了这个错误 类型不匹配(Swift.Dictionary,Swift.DecodingError.Context(codingPath:[CodingKeys(stringValue:“txt_forecast”,intValue:nil)],debugDescription:“应该解码字典,但找到了数组。”,underlineingerror:nil)) 以下是我使用的代码: struct container: Dec

我试图在codable的帮助下解码JSON-

然而,当我这样做的时候,我得到了这个错误

类型不匹配(Swift.Dictionary,Swift.DecodingError.Context(codingPath:[CodingKeys(stringValue:“txt_forecast”,intValue:nil)],debugDescription:“应该解码字典,但找到了数组。”,underlineingerror:nil))

以下是我使用的代码:

struct container: Decodable {
    var days: [forecastDay]

    //Coding keys
    enum CodingKeys: String, CodingKey {
        case forecast = "forecast"
        case txt_forecast = "txt_forecast"
        case forecastday = "forecastday"
    }

    // Decoding
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let forecast = try container.nestedContainer(keyedBy: CodingKeys.self, forKey: .forecast)
        let txt_forecast = try forecast.nestedContainer(keyedBy: CodingKeys.self, forKey: .txt_forecast)
        let forecastdays = try txt_forecast.nestedContainer(keyedBy: CodingKeys.self, forKey: .forecastday)

        let forecastdaysData = try forecastdays.decode(String.self, forKey: .forecastday)

        days = try JSONDecoder().decode([forecastDay].self, from: forecastdaysData.data(using: .utf8)!)

        print(days)

    }
}

struct forecastDay: Decodable {
    var period: Int?
    var icon: String?
    var title: String?
    var fcttext: String?

    //Coding keys
    enum CodingKeys: String, CodingKey {
            case period = "period"
            case icon = "icon"
            case title = "title"
            case fcttext = "fcttext"
    }

    // Decoding
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        period = try container.decode(Int.self, forKey: .period)

        icon = try container.decode(String.self, forKey: .icon)

        title = try container.decode(String.self, forKey: .title)

        fcttext = try container.decode(String.self, forKey: .fcttext)
    }
}

forecastDay
中的变量名与JSON中的键没有区别,并且
init(来自解码器:)
也不做任何自定义操作,因此可以简化预测日期间的结构

struct ForecastDayPeriod: Decodable {
    let period: Int
    let icon: String
    let title: String
    let fcttext: String
}
现在最好对JSON中的每个级别使用带有键的枚举。另外,
init(来自解码器:)
不应创建新的
JSONDecoder

struct ForecastDay: Decodable {

    let periods: [ForecastDayPeriod]

    enum CodingKeys: String, CodingKey {
        case forecast
    }

    enum ForecastKeys: String, CodingKey {
        case txtForecast = "txt_forecast"
    }

    enum TxtForecastKeys: String, CodingKey {
        case forecastday
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        let forecast = try values.nestedContainer(keyedBy: ForecastKeys.self,
                                                  forKey: .forecast)
        let txtForecast = try forecast.nestedContainer(keyedBy: TxtForecastKeys.self,
                                                       forKey: .txtForecast)

        periods = try txtForecast.decode([ForecastDayPeriod].self,
                                         forKey: .forecastday)        
    }

}
现在应该可以从pastebin示例中解码JSON了

do {
    let jsonData: Data = ...
    let forecastDay = try JSONDecoder().decode(ForecastDay.self, from: jsonData)
} catch {
    print("Error: \(error)")
}