Ios 如何使用FIrebase将带有对象的字典附加到数组

Ios 如何使用FIrebase将带有对象的字典附加到数组,ios,swift,firebase,firebase-realtime-database,Ios,Swift,Firebase,Firebase Realtime Database,我正在与firebase合作,我能得到一本字典,看起来像这样: ▿ 0 : 2 elements - key : "maskForHair" ▿ value : 3 elements ▿ 0 : 2 elements - key : id - value : 1 ▿ 1 : 2 elements - key : name - value : Hair Mask ▿ 2 : 2 el

我正在与firebase合作,我能得到一本字典,看起来像这样:

▿ 0 : 2 elements
    - key : "maskForHair"
    ▿ value : 3 elements
      ▿ 0 : 2 elements
        - key : id
        - value : 1
      ▿ 1 : 2 elements
        - key : name
        - value : Hair Mask
      ▿ 2 : 2 elements
        - key : note
        - value : asd
  ▿ 1 : 2 elements
    - key : "hairShampo"
    ▿ value : 3 elements
      ▿ 0 : 2 elements
        - key : id
        - value : 0
      ▿ 1 : 2 elements
        - key : name
        - value : hairShampo
      ▿ 2 : 2 elements
        - key : note
        - value : asd
let children = snapshot.children.compactMap { $0 as? DataSnapshot }
let cateroryDictionaries = children.compactMap { $0.value as? [String:Any] }
let categories = cateroryDictionaries.map { dict -> HairCategory in
    return HairCategory.init(dictionary: dict)
}
现在我试图用这个字典填充一个tableView,但是我找不到一种方法将这个dict附加到一个数组中,有什么想法吗

下面是我的getCategories函数的外观:

func getCategories(){

    dbHandle = dbRefernce?.child("categories").observe(.value, with: { (snapshot) in
        if let dictionary = snapshot.value as? [String : Any]{

            print(dictionary)

            let category = Categories(dictionary: dictionary)
            self.categoriesArr.append(category)

            DispatchQueue.main.async {
                self.categoriesTableView.reloadData()
            }
        }
    })
}
import Foundation
import UIKit

class Categories: NSObject {

    var name : String? = nil
    var id : Int? = nil
    var note : String? = nil

    init (dictionary: [String: Any]) {
        super.init()
        name = dictionary["name"] as? String
        id = dictionary["id"] as? Int
        note = dictionary["note"] as? String
    }

}
下面是我的Categories类的外观:

func getCategories(){

    dbHandle = dbRefernce?.child("categories").observe(.value, with: { (snapshot) in
        if let dictionary = snapshot.value as? [String : Any]{

            print(dictionary)

            let category = Categories(dictionary: dictionary)
            self.categoriesArr.append(category)

            DispatchQueue.main.async {
                self.categoriesTableView.reloadData()
            }
        }
    })
}
import Foundation
import UIKit

class Categories: NSObject {

    var name : String? = nil
    var id : Int? = nil
    var note : String? = nil

    init (dictionary: [String: Any]) {
        super.init()
        name = dictionary["name"] as? String
        id = dictionary["id"] as? Int
        note = dictionary["note"] as? String
    }

}

首先,我会将您的模型重命名为类似于
HairCategory
的单数形式

您需要迭代从数据库接收的快照的子项。每个子项都应该是一个
[String:Any]
字典,然后可以将其转换为
发型分类

大概是这样的:

▿ 0 : 2 elements
    - key : "maskForHair"
    ▿ value : 3 elements
      ▿ 0 : 2 elements
        - key : id
        - value : 1
      ▿ 1 : 2 elements
        - key : name
        - value : Hair Mask
      ▿ 2 : 2 elements
        - key : note
        - value : asd
  ▿ 1 : 2 elements
    - key : "hairShampo"
    ▿ value : 3 elements
      ▿ 0 : 2 elements
        - key : id
        - value : 0
      ▿ 1 : 2 elements
        - key : name
        - value : hairShampo
      ▿ 2 : 2 elements
        - key : note
        - value : asd
let children = snapshot.children.compactMap { $0 as? DataSnapshot }
let cateroryDictionaries = children.compactMap { $0.value as? [String:Any] }
let categories = cateroryDictionaries.map { dict -> HairCategory in
    return HairCategory.init(dictionary: dict)
}
然后,
类别
的类型为:
[HairCategory]
。如果您还将您的
self.categoriesArr
设置为
[HairCategory]
类型,则可以附加新获取的类别:)

编辑

我还可以建议您看看这个库: . 它使从DataSnapshot到模型的转换变得非常简单

编辑


只是想澄清一下。。。您不能“将字典…附加到数组”,您需要将字典转换为数组,然后您可以将该数组附加到相同类型的另一个数组:)

我就是这样计算的:

 for index in 1...self.numberOfProducts{

        dbHandle = dbRefernce?.child("categories").child("\(index)").observe(.value, with: { (snapshot) in
            guard let value = snapshot.value as? [String: Any] else { return }
            guard let name = value["name"] as? String,
                let imageURL = value["imageURL"] as? String,
                let desc = value["description"] as? String,
                let price  = value["price"] as? Int,
                let id = value["subCategoryID"] as? Int
                else {return}


            let category = Product(name: name, imageURL: imageURL, description: desc, price: price,subCategoryID: id)

            self.productsArr.append(category)
            self.tblProducts.reloadData()
        })
    }
刚刚创建了一个对象,然后将其附加到数组中,
你可以循环执行此操作

你可以打印此打印(字典)@AbdelahadDarwish你好,我已经在第一段代码中完成了。有一些问题。1) 松开DispatchQueue.main.async,因为firebase闭包无论如何都会在主线程上运行2)您正在读取整个categories节点,其中包括所有子节点。这与Categories类不匹配,因为它只需要一个节点。3) 要解决此问题,您应该迭代快照中返回的子节点,并为每个子节点创建一个类别,而不是一次创建所有子节点。哦,为了进一步了解#3,每个子节点(maskForHair、hairShampo等)都有多个子节点。同样,这与您的Category类不匹配,因为它希望每个子节点都是单独的,所以它们也需要迭代。嗨,谢谢您的回答,我试图创建一个类别菜单,所以我不能为每个类别创建一个类,因为我试图让代码知道如何在不接触代码本身的情况下单独处理从服务器端添加的新类别。我将查看该库并进行更新。但只要每个类别都有
名称
id
注释
,您就应该能够对它们使用相同的模型。否则,您可以使用协议让多个模型类型实现相同的功能,例如在
init(dictionary:)
。我不认为这个库可以单独解决您的问题,但它可以在上面添加一些很好的糖。为什么不能在数组中附加一个字典呢?数组可以容纳多种对象,如字符串、整数、对象、字典、结构等。OP的字典包含所有子注释,因此这是不对的,但您当然可以将字典附加到数组中。