Swift 3 和 Firebase - Tableview 未更新

Posted

技术标签:

【中文标题】Swift 3 和 Firebase - Tableview 未更新【英文标题】:Swift 3 and Firebase - Tableview not updating 【发布时间】:2017-05-05 18:12:07 【问题描述】:

Swift 3 和 Firebase - 我已经成功地在表格视图单元格中获取用户的用户名和电子邮件地址。但是,当用户在单独的视图控制器上更改他的用户名时,tableview 不会更新 - 旧的用户名仍然显示。请看下面的代码:

 databaseRef.child("users").queryOrdered(byChild: "username").observe(.childAdded, with:  (snapshot) in

        let key = snapshot.key
        let snapshot = snapshot.value as? NSDictionary
        snapshot?.setValue(key, forKey: "uid")

        if(key == self.loggedInUser?.uid)
        
            // don't add signed in user to array
        
        else
        
            var theUser = User()
            theUser.key = key
            theUser.fullname = snapshot?.value(forKey: "fullname") as? String
            theUser.biography = snapshot?.value(forKey: "biography") as? String
            theUser.location = snapshot?.value(forKey: "location") as? String
            theUser.photoURL = snapshot?.value(forKey: "photourl") as? String
            theUser.username = snapshot?.value(forKey: "username") as? String
            self.arrayOfUsers.append(theUser)
            //insert the rows
            self.SearchUsersTableViewController.insertRows(at: [IndexPath(row:self.arrayOfUsers.count-1,section:0)], with: UITableViewRowAnimation.automatic)

                self.tableView.reloadData()

        
    )

我尝试将 tableview.reloadData() 放置在多个地方但没有成功。我也尝试过使用:

DispatchQueue.main.async 
  self.tableView.reloadData()

没有成功。我想出了一个想法,当他更改用户名时再次附加用户。但是,我不知道如何删除旧的。我认为最好的解决方案是添加 childChanged 类型的观察。问题是我在 users 数组中找不到更改用户名的用户的索引。

如果有人帮助我解决问题,我将不胜感激。

编辑:

我有一个结构用户:

struct User 
    var username: String?
    var photoURL: String?
    var biography: String?
    var fullname: String?
    var location: String?
    var key: String?

对于 .childChanged,我使用了 Priyamal 建议的代码:

databaseRef.observe(.childChanged, with:  snapshot in
        let ID = snapshot.key //this is the firebaseKey
        if let index = self.arrayOfUsers.index(where: $0.key == ID) 
            let changedPost = self.arrayOfUsers[index]
            //update the values
                self.tableView.reloadData()
                print("Change!")
        
    )

但是,当我更改用户名时,我永远不会进入“更改!”在我的控制台中输出;因此,tableview 没有改变。

【问题讨论】:

【参考方案1】:

我认为您需要将事件类型从 childAdded 更改为 childChanged 随着孩子的改变,你只会得到更新的价值。那么您必须更新数组中的现有元素。

让我们假设你的用户结构看起来像这样

struct User 
    var keyID : String?
    var name : String?


    var userArray = [User]() //this represents the array holding user objects 

如果发生更新,将调用此方法

    databaseRef.observeEventType(.ChildChanged, withBlock:  snapshot in
  let ID = snapshot.key //this is the firebaseKey
  if let index = self. userArray.indexOf($0.keyID == ID) 
    let changedPost = self. userArray[index]
    //update the values
    self.tableView.reloadData
   

首先加载 UserArray 使用此方法。

databaseRef.child("users").queryOrdered(byChild: "username").observe(.value, with:  (snapshot) in

        let key = snapshot.key
        let snapshot = snapshot.value as? NSDictionary
        snapshot?.setValue(key, forKey: "uid")

        if(key == self.loggedInUser?.uid)
        
            print("Should not be shown!")
        
        else
        
            self.usersArray.append(snapshot)
            self.SearchUsersTableViewController.insertRows(at: [IndexPath(row:self.usersArray.count-1,section:0)], with: UITableViewRowAnimation.automatic)

                self.tableView.reloadData()

        
    )

【讨论】:

那么数组根本没有填充。它只能通过使用 .childAdded (甚至不是 .value)来填充 我收到一个错误:'NSDictionary?' 类型的值此行没有成员“keyID”:if let index = self.usersArray.indexOf($0.keyID == ID) 看看我的struct User 它包含KeyID 属性,你可能没有一个名为User 的结构,其属性为KeyID。似乎您正在填充传递快照的用户数组,不要立即传递快照。读取值并首先创建一个用户对象,然后将其插入到 UserArray 我已经更新了问题!我创建了一个 struct User 并创建了 User 类型的对象并将它们添加到数组中。它们已成功填充到 tableview 中,但是正如您在上面看到的, .childChanged 不知何故不起作用。此外,常量 changedPost 仍未使用。谢谢! 另外,当我使用 .childAdded 的 .value insted 时,根本不会填充数组。【参考方案2】:

我已经成功解决了这个问题。获得索引后,我只需要更新数组中特定位置的用户并刷新表格视图中的特定行!

databaseRef.child("users").queryOrdered(byChild: "username").observe(.childChanged, with:  (snapshot) in
        let ID = snapshot.key
        if let index = self.arrayOfUsers.index(where: $0.key == ID) 
            let value = snapshot.value as? NSDictionary
            self.arrayOfUsers[index].username = value?["username"] as? String
            let indexPath = IndexPath(item: index, section: 0)
            self.tableView.reloadRows(at: [indexPath], with: .top)
        
    )

【讨论】:

以上是关于Swift 3 和 Firebase - Tableview 未更新的主要内容,如果未能解决你的问题,请参考以下文章

读取引发的 Firebase 身份验证错误(Firebase 3.x 和 Swift)

Swift 3 和 Firebase - Tableview 未更新

设置值 Firebase - Swift 3

致命错误:索引超出范围 - Swift 3 和 Firebase

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

Xcode8/Swift 3 更新后缺少 Firebase 标头警告