在 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 数组?的主要内容,如果未能解决你的问题,请参考以下文章

在 PHP 代码中嵌入 HTML

如何将嵌入的 json 分配给 Swift 中的变量?

循环遍历具有子数组的嵌入式文档并将它们显示在 EJS 文档上

如何在 MongoDB 的嵌入式数组对象中插入 json 对象?

嵌入在容器中的 Swift 表格视图

将 JSON 中的值获取到 discord.js 嵌入中