Arrays 如何使用用户节点下的节点创建列表?

Arrays 如何使用用户节点下的节点创建列表?,arrays,swift,xcode,firebase,uitableview,Arrays,Swift,Xcode,Firebase,Uitableview,我试图用一个分段按钮创建两个表,在两个表之间切换。我目前有代码来切换这两个表的可见性。我正在使用firebase,希望能够通过我放在用户json树中的特定标记来区分用户 例如: Users: | 4774893HUjd8 | Name: John Doe Email: example@example.com Tag: Macro | 38849HH

我试图用一个分段按钮创建两个表,在两个表之间切换。我目前有代码来切换这两个表的可见性。我正在使用firebase,希望能够通过我放在用户json树中的特定标记来区分用户

例如:

Users:
     |
    4774893HUjd8
               |
              Name: John Doe
              Email: example@example.com
              Tag: Macro
     |
    38849HHIJDO877
               |
               Name: Jane Doe
               Email: example2@example.com
               Tag: Micro
我希望能够将它们保留在用户节点中。我不想创建宏和微用户节点,因为如果用户升级其帐户,我可以在firebase中更新标记

以下是我当前在项目中加载数据的方式:

func updateDataArray() {
    
    Database.database().reference().child("Users").observe(.childAdded, with: { (snapshot) in
        
        if let dictionary = snapshot.value as? [String: AnyObject] {
            
            let user = User()
            //self.setValuesForKeys(dictionary)
            user.Name = dictionary["Name"] as? String
            user.Email = dictionary["Email"] as? String
            user.ProfileImageUrl = dictionary["ProfileImageUrl"] as? String
            user.UID = dictionary["UID"] as? String
            user.UserCategory = dictionary["UserCategory"] as? String
            
            self.users.append(user)
            self.userName.append(user.Name!)
            self.filteredNames.append(user.Name!)
            
            print(dictionary)
            
            DispatchQueue.main.async {
            self.tableView.reloadData()
                }
            }
        }, withCancel: nil)
    }
我使用swift和firebase作为后端。我真的需要帮助,希望尽快解决这个问题

编辑:这是我的用户结构,可能会有帮助

import UIKit

class User: NSObject {
    var Name: String?
    var Email: String?
    var ProfileImageUrl: String?
    var UID: String?
    var Tag: String?
}
我还添加了您建议的两个不同的数组

我将表计数和输入更改为各自的标记数组

我很难更新children值并附加正确的数组

func createDataArray() {
    
    Database.database().reference().child("Users").observe(.childAdded, with: { (snapshot) in
        
        if let dictionary = snapshot.value as? [String: AnyObject] {
            
            let user = User()
            //self.setValuesForKeys(dictionary)
            user.Name = dictionary["Name"] as? String
            user.Email = dictionary["Email"] as? String
            user.UID = dictionary["UID"] as? String
            user.Tag = dictionary["Tag"] as? String
            
            if user.Tag == "Macro" {
                            self.macroUsersArray.append(user)
            } else if user.Tag == "Micro" {
                            self.microUsersArray.append(user)
                        }
            
            self.users.append(user)
            self.userName.append(user.Name!)
            self.filteredNames.append(user.Name!)
            
            print(dictionary)
            print(self.macroUsersArray)
            
            DispatchQueue.main.async {
            self.tableView.reloadData()
                }
            }
        }, withCancel: nil)
    }
下面是我试图用来删除已更新的子节点标记和更新表数组的代码

func updateDataArray() {
    
    Database.database().reference().child("Users").observe(.childChanged, with: { (snapshot) in
        
        if let dictionary = snapshot.value as? [String: AnyObject] {
            
            let user = User()
            //self.setValuesForKeys(dictionary)
            user.Name = dictionary["Name"] as? String
            user.Email = dictionary["Email"] as? String
            user.UID = dictionary["UID"] as? String
            user.Tag = dictionary["Tag"] as? String
            
            if user.Tag == "Macro" {
                self.microUsersArray.removeAll()
            } else if user.Tag == "Micro" {
                self.macroUsersArray.removeAll()
                        }
            
            self.users.append(user)
            self.userName.append(user.Name!)
            self.filteredNames.append(user.Name!)
            
            print(dictionary)
            print(self.macroUsersArray)
            
            DispatchQueue.main.async {
            self.tableView.reloadData()
                }
            }
        }, withCancel: nil)
    
    }

我不确定我是否理解这个问题,但从OP希望在所有用户中读取的注释中可以看出,根据子节点,将它们分为两个列表,即用作tableView数据源的Micro和Macro

从用户类开始保存用户信息

class UserClass {
    var uid = ""
    var name = ""
    var email = ""
    var tag = ""

    convenience init(withSnap: DataSnapshot) {
        self.init()
        self.uid = withSnap.key
        self.name = withSnap.childSnapshot(forPath: "Name").value as? String ?? "No Name"
        self.email = withSnap.childSnapshot(forPath: "Email").value as? String ?? "No Email"
        self.tag = withSnap.childSnapshot(forPath: "Tag").value as? String ?? "Micro"
    }
}
然后使用两个数组作为tableView数据源。一个包含微用户,另一个包含宏用户。这些变量通常是tableViewDataSource函数可以访问的类变量:

var macroUsersArray = [UserClass]()
var microUsersArray = [UserClass]()
然后将Firebase代码读入所有用户,对其进行迭代,然后添加到适当的数组中

func readAllUsersAndAddToDatasource() {
    let usersRef = self.ref.child("Users")
    usersRef.observeSingleEvent(of: .value, with: { snapshot in
        let allUsersSnap = snapshot.children.allObjects as! [DataSnapshot]
        for childSnap in allUsersSnap {
            let user = UserClass(withSnapshot: childsnap)
            if user.Tag = "Macro" {
                self.macroUsersArray.append(user)
            } else {
                self.microUsersArray.append(user)
            }
        }
    })
}
编辑:

如果我们不使用Firebase事件,一种可能的工作流,例如,用户由observeSingleEvent读取,如上所示

在宏数组中选择要从宏更改为微的用户 更改用户属性 从宏数组中删除用户重新加载宏表视图 将用户添加到Micro array重新加载Micro tableView 在Firebase中更新用户的属性 如果您使用的是事件,那么模式就不同了

将.changed事件添加到用户节点以监视更改

在宏数组中选择要从宏更改为微的用户 获取用户密钥uid并将更改写入firebase,触发更改事件 在已更改的闭包中,从宏数组重载表视图中删除用户 将用户添加到微阵列重新加载表视图
两件事;您可能应该使用用户uid作为用户节点内其节点的键,例如/users/uid\x。第二件事是,你在问什么,什么不起作用?这个问题提到创建一个列表,但代码中没有这方面的指示-一个列表。。。什么的?其他用户?最喜欢的食物?哦,还有这个用户名!是危险的,因为它是可选的?一串firebase闭包中不需要这个DispatchQueue.main.async,因为UI调用是在主线程上自动调用的。谢谢你的评论。我希望能够将用户加载到两个不同的组中,以显示在两个不同的表中。我希望将所有的用户都加载到相同的位置,然后通过每个用户节点下的标记来区分它们。在我的示例中,标记是宏和微。我希望能够访问所有其他信息以及标签,以便标签不能位于所有其他信息之前。我还希望能够在不必重新输入信息的情况下,将标签从宏更新到微,或从宏更新到微。这样我就可以用零钱把它们放到桌子上了。我忘了说我编的那些数字是UID。嘿,杰。在你的帮助下,我很快就能解决这个问题了。我编辑了我的问题,为你们提供了更多的信息,并告诉你们我目前在哪里。再次感谢你的帮助。希望这对你来说是一个超级快速的解决方案,这样我就可以在其他问题出现之前让你休息一下哈哈。@NewCoder请记住,从概念上讲,如果你有两个数组,一个用于微用户,一个用于宏用户,并且你将一个用户从一个数组更改为另一个,你需要将它们从一个数组中删除并添加到另一个数组中,然后刷新tableView以反映该更改。也就是说,根据您使用firebase的方式,您可能希望观察.childAdded、.childChanged和.childRemoved的相关对象,因此如果您对firebase本身进行更改,您的代码将自动意识到该更改,并可以更新相应的数据源数组。哦,太棒了。我提前向您道歉,但是当我在firebase中更改标签时,我该如何设置它?它只是在应用程序上更新而已?@NewCoder这将取决于您的用例。我的答案是一次加载所有用户并将其放入相应的数组中,而您的代码添加了一个观察者来观察未来添加的事件。我不知道你到底想不想这么做。有两种选择;1根据我的答案加载用户a
nd当某些内容发生更改时,将该数据写入Firebase并在数组中进行更改。2将数据写入Firebase,让Firebase观察员根据这些事件更新阵列。有关我尝试更改observe.child的事件的详细信息已添加到observe.ChildChanged,并且该表现在未加载。我想用你的第二个例子。我可以在firebase中更改用户标签,并在所有用户的应用程序上自动更改。