不能在“任何”SWIFT类型的非可选值上使用可选链接

时间:2016-11-23 14:37:45

标签: ios json swift

我对Swift非常陌生,我在构建一个利用来自openweathermap.org网站的API的天气应用程序时遇到了麻烦。当用户进入城市并点击“提交”时,他们应该能够看到显示天气描述的标签。

JSON中的结果是:

(
        {
        description = haze;
        icon = 50d;
        id = 721;
        main = Haze;
    },
        {
        description = mist;
        icon = 50d;
        id = 701;
        main = Mist;
    }
)

在尝试调试时,我使用了代码:print(jsonResult [“weather”]!)这让我可以看到上面的JSON细节。但是,当我试图获得天气的描述时,我似乎无法让它工作。

我的目标:我想在我的应用上显示天气的描述。我目前收到错误:无法对“Any”类型的非可选值使用可选链接。非常感谢您的帮助!

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var cityTextField: UITextField!

    @IBOutlet weak var resultLabel: UILabel!


    @IBAction func submit(_ sender: AnyObject) {
        // getting a url
        if let url = URL(string: "http://api.openweathermap.org/data/2.5/weather?q=" + (cityTextField.text?.replacingOccurrences(of: " ", with: "%20"))! + ",uk&appid=08b5523cb95dde0e2f68845a635f14db") {

        // creating a task from the url to get the content of that url
        let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
            if error != nil {
                print("error")
            } else {
                print("no error")
                if let urlContent = data {
                    do {
                        let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:Any]
                        //print(jsonResult["weather"]!)
                        if let description = jsonResult["weather"]??[0]["description"] as? String {
                            DispatchQueue.main.sync(execute:{
                                self.resultLabel.text = description
                            })
                        }
                    } catch {
                        print("JSON processing failed")
                    }
                }
            }
        }
        task.resume()
        } else {
            resultLabel.text = "Couldn't find weather for that city. Please try a different city."
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    }

2 个答案:

答案 0 :(得分:1)

试试这个

let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:Any]


    let weather = jsonResult["weather"] as! [[String : Any]]
    if let description = weather[0]["description"] as? String {

        print(description)
    }

答案 1 :(得分:0)

你在这里使用“??”

混淆了编译器
if let description = jsonResult["weather"]??[0]

正确的语法只是使用一个“?”

if let description = jsonResult["weather"]?[0]

但是接下来你会得到另一个错误:

let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:Any]  

您说jsonResult["weather"会为您提供Any类型。不要输入数组。

所以你需要打开像下面这样的数组:

if let descriptions = jsonResult["weather"] as? [[String : Any]], let description = descriptions[0]

等等。