swift - 无法将类型 '[String : Any]' 的值转换为预期参数类型 'Data' Alamofire - 可编码

标签 swift xcode10.1

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

我已经尝试过response.data,它确实为我提供了数据作为可选项,但我不知道如何在这次调用中解开该可选项。我已经搜索并发现 result.value 可能更接近我需要的。以下是我到目前为止所拥有的。这会导致“无法将类型‘[String : Any]’的值转换为预期参数类型‘数据’”错误。

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 数据打印到表格 View 中,包括图像和日期。我认为能够解开这个 optional 是我弄清楚下一部分之前的第一步。

最佳答案

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)
}

关于swift - 无法将类型 '[String : Any]' 的值转换为预期参数类型 'Data' Alamofire - 可编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57651184/

相关文章:

ios - iOS中如何根据不同用户类型动态切换UI主题

swift - 命令行工具中的框架问题

ios - 如何在进行中重新启动 CALayer 动画?

ios - 创建自定义 tableView 单元格 textField 或 textView 标签

ios - Carthage 更新失败,提示 "Could not find any available simulators for iOS"- Xcode 10.1、macOS Mojave (10.14.2)

ios - 找不到用 swift 类编写的 Objective-C 类中选择器的已知类方法

ios - 如何在横向 View Controller 中快速显示网页 View ?

ios - 在 awakeFromNib() 上 - 错误实例成员 'button' 不能在类型 'CustomView' 上使用

ios - 大型纹理图集因内存压力而导致终止

ios - 每当我点击里面的整个应用程序时播放点击声音