您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

在Swift 3中正确解析JSON

在Swift 3中正确解析JSON

首先, ,而应始终使用异步方法,例如URLSession

‘Any’没有下标成员

是因为编译器没有什么类型的中间对象(例如理念currently["currently"]!["temperature"]),并且由于使用的是基金会收藏类型,如NSDictionary编译器在所有有关的类型不知道。

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

代码的用途URLSession和 斯威夫特本地类型

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

许多(看来都是)教程建议.mutableContainers.mutableLeaves选项在Swift中完全是胡说八道。这两个选项是遗留的Objective- C选项,用于将结果分配给NSMutable...对象。在Swift中var认情况下任何变量都是可变的,并且传递这些选项中的任何一个并将结果分配给let常量都完全无效。此外,大多数实现绝不会改变反序列化的JSON。

唯一的(罕见)选项,在夫特是有用是.allowFragments如果如果JSON根对象可以是一个值类型是必需(StringNumberBoolnull)而不是集合类型中的一个arraydictionary)。但通常会省略options表示No options 的参数。

================================================== =========================

JSON是一种排列合理的文本格式。读取JSON字符串非常容易。 。只有六种不同的类型–两种收集类型和四种值类型。

收集类型为

值类型为

根据JSON规范,字典中的所有键都必须为String

如果根对象是字典({}),则将类型强制转换为[String:Any]

if let parsedData = try JSONSerialization.jsonObject(with: data!) as? [String:Any] { ...

并使用(OneOfSupportedJSONTypes是JSON集合或如上所述的值类型)通过键检索值。

if let foo = parsedData["foo"] as? OneOfSupportedJSONTypes {
    print(foo)
}

如果根对象是数组([]),则将类型强制转换为[[String:Any]]

if let parsedData = try JSONSerialization.jsonObject(with: data!) as? [[String:Any]] { ...

并通过遍历数组

for item in parsedData {
    print(item)
}

如果您需要特定索引处的项目,还检查索引是否存在

if let parsedData = try JSONSerialization.jsonObject(with: data!) as? [[String:Any]], parsedData.count > 2,
   let item = parsedData[2] as? OneOfSupportedJSONTypes {
      print(item)
    }
}

在极少数情况下,JSON只是值类型之一(而不是集合类型),您必须传递.allowFragments选项并将结果转换为适当的值类型,例如

if let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? String { ...

苹果在Swift博客中发表了一篇详尽的文章在Swift中使用JSON

================================================== =========================

例如,问题中的给定JSON示例(稍作修改

let jsonString = """
{"icon": "partly-cloudy-night", "precipProbability": 0, "pressure": 1015.39, "humidity": 0.75, "precip_intensity": 0, "wind_speed": 6.04, "summary": "Partly Cloudy", "ozone": 321.13, "temperature": 49.45, "dew_point": 41.75, "apparent_temperature": 47, "wind_bearing": 332, "cloud_cover": 0.28, "time": 1480846460}
"""

可以解码为struct Weather。Swift类型与上述相同。还有一些其他选项:

struct Weather: Decodable {
    let icon, summary: String
    let pressure: Double, humidity, windSpeed : Double
    let ozone, temperature, dewPoint, cloudCover: Double
    let precipProbability, precipIntensity, apparentTemperature, windBearing : Int
    let time: Date
}

let data = Data(jsonString.utf8)
do {
    let decoder = JSONDecoder()
    decoder.dateDecodingStrategy = .secondsSince1970
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let result = try decoder.decode(Weather.self, from: data)
    print(result)
} catch {
    print(error)
}

其他可编码来源:

Swift 2022/1/1 18:19:00 有270人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶