我想在tableView中显示当前的用户朋友,但是我无法让它完美地工作,当列表中的某个人改变他的名字时,该单元格会重复。
JSON:
{
"users" : {
"friends_requests" : {
"EeLIxkOEfhMUlsM8WGnHdgeT8xW2" : {
"friends" : {
"WWOdh96Yr3Qs4N3GWDVq3OlQFfB2" : true
}
},
"WWOdh96Yr3Qs4N3GWDVq3OlQFfB2" : {
"friends" : {
"EeLIxkOEfhMUlsM8WGnHdgeT8xW2" : true
}
}
},
"profile" : {
"EeLIxkOEfhMUlsM8WGnHdgeT8xW2" : {
"birthday" : "02/08/2017",
"displayname" : "user2",
"email" : "11@1.1",
"gender" : "M"
},
"WWOdh96Yr3Qs4N3GWDVq3OlQFfB2" : {
"birthday" : "02/08/2017",
"displayname" : "user1",
"email" : "112@2.1",
"gender" : "M"
}
}
}
}
以下是代码:
var friendList = [Userr]()
func addFriendObserver(_ update: @escaping () -> Void) {
CURRENT_USER_FRIENDS_REF.observe(.value, with: { (snapshot) in
self.friendList.removeAll()
let enumerator = snapshot.children
while let rest = enumerator.nextObject() as? FIRDataSnapshot {
self.ref.child("users").child("profile").child(rest.key).observe(.value, with: { (snapshot) in
guard let dictionary = snapshot.value as? [String: Any] else {
return
}
let user = Userr()
user.displayname = dictionary["displayname"] as? String
self.friendList.append(user)
DispatchQueue.main.async {
self.tableview.reloadData()
}
}, withCancel: nil)
我尝试了很多方法,多次问过这个问题,但仍然无法让它起作用,也没有答案。
请有人帮我解决这个问题。
编辑:我使用的新观察者:
func showUsersObserver(_ update: @escaping () -> Void) {
CURRENT_USER_FRIENDS_REF.observe(.value, with: { (snapshot) in
self.friendList.removeAll()
let keys = snapshot.children
while let rest = keys.nextObject() as? FIRDataSnapshot {
self.getUser(rest.key, completion: { (user) in
self.friendList.append(user)
print(self.friendList.count) // This increase each time when user changing his name! or any changes hits his profile.
DispatchQueue.main.async {
self.tableview.reloadData()
}
update()
})
}
// If there are no children, run completion here instead
if snapshot.childrenCount == 0 {
update()
}
})
}
这是为了获取他们的个人资料数据:
func getUser(_ userID: String, completion: @escaping (User) -> Void) {
USER_REF.child(userID).observe(.value, with: { (snapshot) in
guard let dictionary = snapshot.value as? [String: Any] else {
return
}
let id = dictionary["uid"] as? String
let email = dictionary["email"] as? String
let DisplayName = dictionary["displayname"] as? String
completion(User(userEmail: email!, userID: id!, userDisplayName: DisplayName!))
})
}
和朋友列表:
class User {
var uid: String!
var displayname: String!
var email: String!
init(userEmail: String, userID: String, userDisplayName: String) {
self.email = userEmail
self.uid = userID
self.displayname = userDisplayName
}
}
我正在使用Userr进行测试。但用户是主要的快速文件。
答案 0 :(得分:0)
尝试更改
self.ref.child("users").child("profile").child(rest.key).observe(.value, with: { (snapshot) in
...
})
到
self.ref.child("users").child("profile").child(rest.key).observeSingleEvent(of: .value, with: { (snapshot) in
...
})
每次参考路径中的数据发生更改时, .observe
都会导致...
中的代码运行。因此,每次更改参考路径中的数据时,都会附加到friendList
。 .observeSingleEvent
确保代码只执行一次。
如果您希望在用户的数据发生变化时更新单元格,请继续使用.observe
并在闭包内执行此操作:
让用户拥有一个名为uid的属性,用于用户的推送键
guard let dictionary = snapshot.value as? [String: Any] else {
return
}
let userID = snapshot.key
if let friend = self.friendsList.first(where: {$0.uid == userID}) {
friend.displayname = dictionary["displayname"] as? String
friend.email = dictionary["email"] as? String
friend.uid = dictionary["uid"] as? String
//update any other properties of the User class
completion(friend)
}
else {
let id = dictionary["uid"] as? String
let email = dictionary["email"] as? String
let displayName = dictionary["displayname"] as? String
//update other properties of the User class
let user = User(userEmail:email, userID:id, userDisplayName:displayName)
self.friendsList.append(user)
completion(user)
}
该代码将使得用户的配置文件发生更改时,它将检查friendsList
阵列中的任何用户是否具有相同的用户ID,如果有,则更新匹配userID用户的displayname。如果friendsList
中没有用户与userID匹配,则会将用户追加到friendsList
的末尾,因为它是一个新用户,但尚未在该数组中使用。