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 未更新
致命错误:索引超出范围 - Swift 3 和 Firebase