在Swift3中正确解析JSON

0 投票
最新提问 3月 3 分类:IOS | 用户: 点心 (280 分)

我试图获取一个JSON响应,并将结果存储在变量里。这段代码在以前版本的Swift中可以使用,直到Xcode 8 GM发布。如何正确解析Swift 3中的JSON响应?在Swift 3中读取JSON的方式有什么变化?

下面是有问题的代码:

import Cocoa

let url = "https://api.forecast.io/forecast/apiKey/37.5673776,122.048951"

if let url = NSURL(string: url) {
    if let data = try? Data(contentsOf: url as URL) {
        do {
            let parsedData = try JSONSerialization.jsonObject(with: data as Data, options: .allowFragments)

        //Store response in NSDictionary for easy access
        let dict = parsedData as? NSDictionary

        let currentConditions = "\(dict!["currently"]!)"

        //This produces an error, Type 'Any' has no subscript members
        let currentTemperatureF = ("\(dict!["currently"]!["temperature"]!!)" as NSString).doubleValue

            //Display all current conditions from API
            print(currentConditions)

            //Output the current temperature in Fahrenheit
            print(currentTemperatureF)

        }
        //else throw an error detailing what went wrong
        catch let error as NSError {
            print("Details of JSON parsing error:\n \(error)")
        }
    }
}

以下是来自API调用的结果的示例print(currentConditions)

["icon": partly-cloudy-night, "precipProbability": 0, "pressure": 1015.39, "humidity": 0.75, "precipIntensity": 0, "windSpeed": 6.04, "summary": Partly Cloudy, "ozone": 321.13, "temperature": 49.45, "dewPoint": 41.75, "apparentTemperature": 47, "windBearing": 332, "cloudCover": 0.28, "time": 1480846460]

1个回答

0 投票
最新回答 3月 3 用户: 花花 (350 分)

首先不要从远程URL同步加载数据,总是使用异步方法URLSession。

“Any”没有下标成员

因为编译器不知道中间对象是什么类型(例如["currently"]!["temperature"]中的currentlyin),并且因为您使用Foundation集合类型如NSDictionary,编译器根本不知道类型。

此外,在Swift 3中,需要通知编译器有关所有下标对象的类型。

您必须将JSON序列化的结果转换为实际类型。

此代码使用URLSession并且专门使用Swift本机类型

let urlString = "https://api.forecast.io/forecast/apiKey/37.5673776,122.048951"

let url = URL(string: urlString)
URLSession.shared.dataTask(with:url!) { (data, response, error) in
  if error != nil {
    print(error)
  } else {
    do {

      let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String:Any]
      let currentConditions = parsedData["currently"] as! [String:Any]

      print(currentConditions)

      let currentTemperatureF = currentConditions["temperature"] as! Double
      print(currentTemperatureF)
    } catch let error as NSError {
      print(error)
    }
  }

}.resume()

要打印所有键/值对,可以这样写currentConditions

 let currentConditions = parsedData["currently"] as! [String:Any]

  for (key, value) in currentConditions {
    print("\(key) - \(value) ")
  }

注:

苹果已经在Swift博客中发表了一篇综合文章:在Swift中使用JSON

欢迎来到编程助手,编程方面有什么不懂的问题可以尽管在这里提问,你将会收到热心爱好者的回答。
...