栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在Swift 3中正确解析JSON

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在Swift 3中正确解析JSON

首先, 永远不要从远程URL同步加载数据 ,而应始终使用异步方法,例如

URLSession

‘Any’没有下标成员

是因为编译器没有什么类型的中间对象(例如理念

currently
["currently"]!["temperature"]
),并且由于使用的是基金会收藏类型,如
NSDictionary
编译器在所有有关的类型不知道。

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

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

此代码的用途

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

关于

jsonObject(with data
以下内容的注释:

许多(看来都是)教程建议

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

唯一的(罕见)选项,在夫特是有用是

.allowFragments
如果如果JSON根对象可以是一个值类型是必需(
String
Number
Bool
null
)而不是集合类型中的一个(
array
dictionary
)。但通常会省略
options
表示
No options 的参数。

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

解析JSON的一些一般注意事项

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


收集类型为

  • 数组 -JSON:方括号中的对象
    []
    -Swift:
    [Any]
    但在大多数情况下
    [[String:Any]]
  • 字典 -JSON:大括号中的对象
    {}
    -Swift:
    [String:Any]

值类型为

  • 字符串 -JSON:双引号中的任何值
    "Foo"
    ,偶数
    "123"
    "false"
    – Swift:
    String
  • 数字 -JSON:数值 不带 双引号
    123
    123.0
    – Swift:
    Int
    Double
  • 布尔 -JSON:
    true
    false
    使用双引号-Swift:
    true
    false
  • null -JSON:
    null
    – Swift:
    NSNull

根据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


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

在Swift 4+中,该
Codable
协议提供了一种将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类型与上述相同。还有一些其他选项:

  • 表示的字符串
    URL
    可以直接解码为
    URL
  • time
    整数可以被解码为
    Date
    与所述
    dateDecodingStrategy
    .secondsSince1970
  • snaked_cased JSON键可被转化为 驼峰
    keyDecodingStrategy
    .convertFromSnakeCase

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 deprer = JSonDeprer()    deprer.dateDecodingStrategy = .secondsSince1970    deprer.keyDecodingStrategy = .convertFromSnakeCase    let result = try deprer.depre(Weather.self, from: data)    print(result)} catch {    print(error)}

其他可编码来源:

  • 苹果:对自定义类型进行编码和解码
  • HackingWithSwift:可编码备忘单
  • Ray Wenderlich:Swift中的编码和解码


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/413203.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号