json - 使用 Swift 访问 JSON 中的嵌套字典
问题描述
我想解析以下JSON,以便从 Wikipedia 的 API 中获取随机文章的 ID 并在 Swift 中使用它:
{
"batchcomplete": "",
"continue": {
"rncontinue": "0.067678657404|0.067678667039|13394072|0",
"continue": "-||"
},
"query": {
"random": [
{
"id": 34538560,
"ns": 3,
"title": "User talk:59.188.42.121"
}
]
}
}
我希望能够从中访问"id"
和"title"
值,我目前可以访问以下内容"query"
:
let url = URL(string: "https://en.wikipedia.org/w/api.php?action=query&list=random&rnlimit=1&format=json")
URLSession.shared.dataTask(with: url!) { (data, response, err) in
guard let data = data else { return }
if err != nil {
print(err!)
} else {
do {
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? NSDictionary
if let result = json! as? [String: AnyObject] {
if let result = result["query"]! as? [String: AnyObject] {
print(result)
}
}
} catch {
print("Error")
}
}
}.resume()
现在,按我的方式进行类型转换并不是我引以为豪的事情,而且它很快就会变得非常混乱。我还通过执行以下操作尝试过一次类型转换,但无济于事:
[String: [String: [String:AnyObject]]]
有没有更好的方法来访问这些值?任何帮助将不胜感激!
解决方案
如果您使用的是 Swift 4,则有Codable
. 使用Codable
涉及为 JSON 定义自定义结构/类,但诸如quicktype.io之类的应用程序可以让这变得轻而易举:您只需粘贴 JSON,它就会为您生成结构。
首先,保存来自维基百科的响应的结构:
struct Response: Codable {
struct Query: Codable {
let random: [Random]
}
struct Random: Codable {
let id, ns: Int
let title: String
}
struct Continue: Codable {
let rncontinue, continueContinue: String
enum CodingKeys: String, CodingKey {
case rncontinue
case continueContinue = "continue"
}
}
let batchcomplete: String
let `continue`: Continue
let query: Query
enum CodingKeys: String, CodingKey {
case batchcomplete, `continue`, query
}
}
并解码 JSON:
let url = URL(string: "https://en.wikipedia.org/w/api.php?action=query&list=random&rnlimit=1&format=json")
URLSession.shared.dataTask(with: url!) { (data, response, err) in
guard let data = data else { return }
guard err == nil else { print(err!); return }
do {
let response = try JSONDecoder().decode(Response.self, from: data)
if let firstArticle = response.query.random.first {
print(firstArticle)
} else {
print("No Article")
}
} catch {
print(error)
}
}.resume()
推荐阅读
- angular - 如果使用掩码='+1 000 000',表格值不会以角度重置
- node.js - 如何将静态 YAML 文件与 React Native 应用程序捆绑在一起?
- java - 使用 Glide 从 URL 加载图像但没有扩展名
- node.js - 节点尝试仅在 :app:bundleReleaseJsAndAssets 阶段查找很久以前删除的包
- c# - 如何反序列化 JSON Api 结果
- ios - 传递 self 并在没有保留循环的情况下在闭包中返回它
- r - 将数据集从长数据集重新格式化为宽数据集
- postgresql - pg_basebackup 所需的磁盘空间
- selenium - 为量角器测试启用 Popups chrome 浏览器
- kubernetes - 卡夫卡经纪人继续重启?