无法将类型“[String : Any]”的值转换为预期的参数类型 'Data' Alamofire - Codable

Cannot convert value of type '[String : Any]' to expected argument type 'Data' Alamofire - Codable

我是编程新手,如果修复很简单,我深表歉意。我正在尝试从 Alamofire 请求中获取 JSON 数据,以便在控制台中不显示为可选数据。

我已经尝试过 response.data,它确实将数据作为可选数据提供给我,但我不知道如何在此调用中解包该可选数据。我搜索过并发现 result.value 可能更接近我的需要。以下是我到目前为止所拥有的。这会导致 "Cannot convert value of type '[String : Any]' to expected argument type 'Data'" 错误。

JSON File-->

"forecasts": [
        {
            "dateLabel": "今日",
            "telop": "晴時々曇",
            "date": "2019-08-16",
            "temperature": {
                "min": null,
                "max": null
            },
            "image": {
                "width": 50,
                "url": "http://weather.livedoor.com/img/icon/2.gif",
                "title": "晴時々曇",
                "height": 31
            }
        },
        {
            "dateLabel": "明日",
            "telop": "晴時々曇",
            "date": "2019-08-17",
            "temperature": {
                "min": {
                    "celsius": "27",
                    "fahrenheit": "80.6"
                },
                "max": {
                    "celsius": "37",
                    "fahrenheit": "98.6"
                }
            },
            "image": {
                "width": 50,
                "url": "http://weather.livedoor.com/img/icon/2.gif",
                "title": "晴時々曇",
                "height": 31
            }
        },
        {
            "dateLabel": "明後日",
            "telop": "晴時々曇",
            "date": "2019-08-18",
            "temperature": {
                "min": null,
                "max": null
            },
            "image": {
                "width": 50,
                "url": "http://weather.livedoor.com/img/icon/2.gif",
                "title": "晴時々曇",
                "height": 31
            }
        }
    ],
    "location": {
        "city": "東京",
        "area": "関東",
        "prefecture": "東京都"
    },
    "publicTime": "2019-08-16T17:00:00+0900",
    "copyright": {
        "provider": [
            {
                "link": "http://tenki.jp/",
                "name": "日本気象協会"
            }
        ],
        "link": "http://weather.livedoor.com/",
        "title": "(C) LINE Corporation",
        "image": {
            "width": 118,
            "link": "http://weather.livedoor.com/",
            "url": "http://weather.livedoor.com/img/cmn/livedoor.gif",
            "title": "livedoor 天気情報",
            "height": 26
        }
    }

Data model-->

import Foundation
import Alamofire

// MARK: - WeatherData
struct WeatherData: Codable {
    let forecasts: [Forecast]
}


struct Forecast: Codable {
    let dateLabel, telop, date: String
    let temperature: Temperature
    let image: Image

    enum CodingKeys: String, CodingKey {
        case dateLabel = "dateLabel"
        case telop = "telop"
        case date = "date"
        case temperature
        case image
    }
}


struct Image: Codable {
    let width: Int
    let url: String
    let title: String
    let height: Int

    enum CodingKeys: String, CodingKey {
        case width = "width"
        case url = "url"
        case title = "title"
        case height = "height"
    }
}


struct Temperature: Codable {
    let min, max: Max?


    enum CodingKeys: String, CodingKey {
        case min = "min"
        case max = "max"

    }

}


struct Max: Codable {
    let celsius, fahrenheit: String


    enum CodingKeys: String, CodingKey {
        case celsius = "celsius"
        case fahrenheit = "fahrenheit"

    }
}

viewcontroller-->

import UIKit
import Alamofire

class ForecastTableViewController: UITableViewController {

    let WEATHER_URL = "http://weather.livedoor.com/forecast/webservice/json/v1?city=130010"


    override func viewDidLoad() {
        super.viewDidLoad()

        Alamofire.request(WEATHER_URL).responseJSON { (response) in

                if let data = response.result.value as? [String: Any]{
                let decoder = JSONDecoder()
                let forecast = try? decoder.decode(WeatherData.self, from: data)
                print(forecast?.forecasts)
            }


                     }
                }

我的最终目标是将 JSON 数据打印到表格视图中,包括图像和日期。我认为能够打开这个可选的是我弄清楚下一部分之前的第一步。

如果您想要访问请求返回的原始 Data,您需要使用 responseDataresponseJSON 使用 JSONSerialization 解析响应并为您提供 Any 值。 responseData 为您提供返回的原始 Data,因此您可以按照当前操作解包并使用 JSONDecoder.

您还可以更新到 Alamofire 5(目前处于测试阶段)并使用 responseDecodable 以便能够自动解析 Decodable 类型。

I've already tried response.data which does give me the data as an optional but I don't know how to unwrap that optional in this call.

您绝对应该学习如何正确解包可选值。它基本上归结为当值为 nil 时你想做什么。 response.data 可能是 nil 当无法获取数据、没有互联网、服务器没有响应或其他任何原因时。

想想在这种情况下你希望发生什么。你想显示一个错误作为对用户的警告吗?你想再试一次,还是什么都不做?

然后使用此代码:

Alamofire.request(WEATHER_URL).responseData { (response) in

    guard let data = response.data else {
        // do the stuff you want to do when the data failed to be fetched
        return
    }
    let decoder = JSONDecoder()
    guard let forecast = try? decoder.decode(WeatherData.self, from: data) else {
        // do the stuff you want to do when the data is not in the right format
        return
    }
    print(forecast?.forecasts)
}