在嵌套的孩子内部迭代。 Firebase 和 Swift 3

Posted

技术标签:

【中文标题】在嵌套的孩子内部迭代。 Firebase 和 Swift 3【英文标题】:Iterate inside a nested child. Firebase and Swift 3 【发布时间】:2017-09-25 13:16:57 【问题描述】:

这是我的数据结构:

 "ItemData": 
    "Item": [
      
        "name": "Table",
        "measurement ": [
          
            "height": 30
          ,
          
            "width": 50
          
        ]
      
    ]
  

我目前可以从 Firebase 获取所有数据,并能够在 tableView 上显示名称。我现在正在尝试获取嵌套在“测量”内的值,即“高度”和“宽度”。我看过Query Firebase for nested child swift、What's the best way of structuring data on firebase?、Iterate through nested snapshot children in Firebase using Swift 和Firebase Swift 3 Xcode 8 - iterate through observe results,但仍然不知道如何解决这个问题。

这是我的 Item 类:

class Item 

    var name: String!
    var measurement: String!
    var key: String

    init(from snapshot: FIRDataSnapshot) 

        let snapshotValue = snapshot.value as? [String: Any]

        self.name = snapshotValue!["name"] as! String
        self.measurement = snapshotValue?["measurement"] as! String
        self.key = snapshot.key

    

这是我用来获取项目的函数。 ItemManager 是一个类,具有删除和添加 Item 数组的功能:

func fetchItem() 

    let databaseRef = FIRDatabase.database().reference(withPath: "ItemData/Item/")

    databaseRef.observe(.value, with:  snapshot in

        ItemManager.shared.removeAll()
        for item in snapshot.children 
            guard let snapshot = item as? FIRDataSnapshot else  continue 


            let item = Item(from: snapshot)
            ItemManager.shared.additem(item)
            print(snapshot)
        

        self.tableView.reloadData()
    )


如果可以的话请帮帮我:)

【问题讨论】:

你遇到了什么错误? 您的第一个问题是measurement 是一个数组,所以它的所有元素都应该是同一类型。但是,您将第一个元素用于height,将下一个元素用于width。如果您对此有控制权,请将度量更改为字典。这样,检索widthheight 将很容易。 @PedroCastilho 我没有收到任何错误。我只是想获得测量值。 @paulvs 感谢您的建议,我明白您的意思,但是我不确定如何实施此更改。我只是让测量成为一个 NSDictionary 吗? 【参考方案1】:

正如评论中建议的measurement 字典数组而不是字符串,所以如果你想从中获取heightwidth,你可以通过这种方式获取。

class Item 

    var name: String!
    var heightMeasurement: String!
    var widthMeasurement: String!
    var key: String

    init(from snapshot: FIRDataSnapshot) 

        let snapshotValue = snapshot.value as? [String: Any]

        self.name = snapshotValue!["name"] as! String
        if let array = snapshotValue["measurement"] as? [[String:Any]], 
           let heightDic = array.first, let height = heightDic["height"],
           let widthDic = array.last, let width = widthDic["width"]             

             self.heightMeasurement = "\(height)"
             self.widthMeasurement = "\(width)"
             print(height, width)
        
        else 
             self.heightMeasurement = "" //set some default value
             self.widthMeasurement = ""  //set some default value
        
        self.key = snapshot.key     
    

注意:如果您的数组有两个以上的对象而不是获取heightwidth,您需要先下标数组索引以获取字典,然后根据得到你的价值。

【讨论】:

感谢 Nirav,但它似乎并没有解决我的问题。您提供的代码不会打印任何内容。 @Chace 尝试将[[String:Int]] 替换为[[String:Any]] 好的,它可以工作并打印出值。但是我怎么称呼它让我们说一个 UIlabel。我试过 cell.heightLbl.text = item.measurement 但什么也没发生,而且很确定是不正确的。 对不起,我会更清楚地说明我希望单独的标签显示测量值有多少(在本例中为 2)。并显示这些值,因此 height = "30" 和 width = "50"。 @Chace 检查编辑后的答案,现在您可以将其设置为 cell.heightLbl.text = item.heightMeasurement 同样适用于宽度

以上是关于在嵌套的孩子内部迭代。 Firebase 和 Swift 3的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法在它的孩子中修改嵌套类的实现?

如何从 Firebase 加载孩子

如何仅在 Firebase 中获取子密钥

如何从 Firebase 检索嵌套数据?应用程序崩溃

Vue - 使用 ref 访问嵌套的孩子

ReferenceError:进程未在 firebase-messaging-sw.js 中定义