在 Swift 中遍历嵌入的 JSON 数组?
Posted
技术标签:
【中文标题】在 Swift 中遍历嵌入的 JSON 数组?【英文标题】:Looping through embedded JSON arrays in Swift? 【发布时间】:2017-07-29 17:14:33 【问题描述】:我正在尝试遍历嵌入的 JSON 数组并提取所有值以放入本地数组中。这是 JSON 的样子:
"welcome":
"data":
"tncUrl": ""
,
"items": [
"newUser": [
"stepConcept": false
,
"stepSafety": true
,
"stepFacilitator": true
,
"stepTransparency": true
],
"switcher": [
"stepConcept": true
,
"stepSafety": true
,
"stepFacilitator": true
,
"stepTransparency": true
]
]
我能够看到我正在检索“newUser”的值,问题是循环遍历这些值并将它们添加到数组中。这样做时我收到 EXC_BAD_INSTRUCTION 错误。这是我用来获取这些值的代码:
func prepareArrayOfViews(userType: User)
if (welcomeJSON != nil)
let items : NSArray? = welcomeJSON!.value(forKey: "items") as? NSArray
if (items == nil)
listOfViews = ["stepConcept", "stepSafety", "stepFacilitator", "stepTransparency"]
maxPages = listOfViews.count
return
if (items != nil)
if let newUser = (items?.value(forKey: "newUser") as? NSArray)
//Below is where the error "EXC_BAD_INSTRUCTION"
for key in (newUser as! NSDictionary).allKeys
if (((newUser as! NSDictionary).value(forKey: key as! String) as? Bool)!)
listOfViews.append(key as! String)
if (listOfViews.count == 0)
listOfViews = ["stepConcept", "stepSafety", "stepFacilitator", "stepTransparency"]
maxPages = listOfViews.count
【问题讨论】:
您负责发送 JSON 吗?如果是,为什么要发送数组中只有一个键的多个字典(而不是 one 字典)? 代码已经到位,我正在重写它以适应新的 json 数据 【参考方案1】:我已更改您的代码以使用本机 Swift 结构。由于当您的可选解包不起作用时您没有处理错误或做任何事情,所以我还将解包更改为保护语句。
除了 Swift 编码实践的严重问题之外,您的问题是您试图将字典数组作为简单字典进行迭代。
func prepareArrayOfViews(userType: User)
guard let welcomeJSON = welcomeJSON else return
guard let items = welcomeJSON["items"] as? [[String:Any]] else
listOfViews = ["stepConcept", "stepSafety", "stepFacilitator", "stepTransparency"]
maxPages = listOfViews.count
return
for item in items
if let newUser = item["newUser"] as? [[String:Any]]
for embeddedDict in newUser
for (key, value) in embeddedDict
if let val = value as? Bool, val == true
listOfViews.append(key)
else if let switcher = item["switcher"] as? [[String:Any]]
for embeddedDict in switcher
for (key, value) in embeddedDict
if let val = value as? Bool, val == true
//do whatever you need to with the value
if (listOfViews.count == 0)
listOfViews = ["stepConcept", "stepSafety", "stepFacilitator", "stepTransparency"]
maxPages = listOfViews.count
【讨论】:
感谢您的帮助,但代码在线给出错误:对于 EmbeddedDict 中的 (key, value) - 类型 '(key: String, value: Any)' 不符合协议'序列' @SwiftyJD 我的错,不小心将newUser
转换为字典而不是字典数组。查看我更新的代码,它现在应该可以工作了。
很高兴我能帮上忙。如果您觉得我的回答有帮助,请采纳。
经过进一步测试,这行代码看起来可能有问题:guard let items = welcomeJSON["items"] as? [String:Any] 因为即使 JSON 可用,它也会直接转到 else 语句
好的,我会通知 API 人员,感谢您的帮助,挽救了我的星期六下午。【参考方案2】:
因为
//here newUser is an NSArray
if let newUser = (items?.value(forKey: "newUser") as? NSArray)
//here newUser forced to NSDictionary
for key in (newUser as! NSDictionary).allKeys
试着把这部分改成
if let newUsers = (items?.value(forKey: "newUser") as? NSArray)
for newUser in newUsers
for key in (newUser as! NSDictionary).allKeys
if (((newUser as! NSDictionary).value(forKey: key as! String) as? Bool)!)
listOfViews.append(key as! String)
【讨论】:
我明白了,我确实需要将 newUser 数组中的项目作为键值对的字典,我是否遗漏了什么? -没关系,我看到你更新了你的答案。 我在这一行收到一个 SIGABRT 错误:for key in (newUser as!NSDictionary).allKeys @SwiftyJD 看到我的答案,它使用原生 Swift 结构并且没有不安全的展开以上是关于在 Swift 中遍历嵌入的 JSON 数组?的主要内容,如果未能解决你的问题,请参考以下文章
循环遍历具有子数组的嵌入式文档并将它们显示在 EJS 文档上