我有这段代码:
func fetchFriends() {
if let window = UIApplication.shared.keyWindow {
guard let userId = Auth.auth().currentUser?.uid else { return }
DispatchQueue.main.async {
FirestoreService.shared.fetchFriendList(userId) { (fetchedFriends) in
//// WONT GET HERE ////
if fetchedFriends != nil {
self.fetchedFriends = fetchedFriends! // Can force unwrap here because we already know that fetchedFriends in not nil.
self.friendsTable.reloadData()
}else {
self.fetchedFriends = []
self.friendsTable.reloadData()
}
}
}
}
}
此代码块正在使用此功能:
func fetchFriendList(_ id: String, completion: @escaping([Friend]?)->()) {
var fetchedFriends: [Friend] = []
db.collection(USERS_COLLECTION).document(id).getDocument { (doc, err) in
if err == nil && doc != nil {
guard let results = doc?.data()?[USER_FOLLOWING] as? [String: Any] else { return }
for result in results { // Getting the data in firebase
if let resultValue = result.value as? [String: Any] { // Getting only the value of the MAP data, we do not need the key.
//Getting the fields from the result
guard let id = resultValue[FRIEND_ID] as? String else { return }
guard let profilePic = resultValue[FRIEND_PROFILE_PIC] as? String else { return }
guard let username = resultValue[FRIEND_NAME] as? String else { return }
guard let email = resultValue[FRIEND_MAIL] as? String else { return }
//Creating a new Friend object from the fields
let friend = Friend(id: id, profilePicture: profilePic, username: username, email: email)
fetchedFriends.append(friend)
}
completion(fetchedFriends)
}
}else {
print(err!.localizedDescription)
completion(fetchedFriends)
}
}
}
这里发生的事情是,我正在进入一个用户文档,从文档中的Map
获取它的“朋友”,创建一个Friend Array
并将其在完成时发送到第一个功能。
在第一个函数中,我正在检查是否得到的是nil
,如果不是,则将其分配给一个数组,否则,如果它为nil,则希望该数组为空。
此处的目的是在tableView
中显示“好友”。
我的问题是这种情况:
首先,朋友列表为空,添加一个朋友并查看列表,我刚刚添加的朋友正在显示,这很好。问题是,当我从列表中删除此朋友(并且在Firestore中的数据库中将其删除)时,再次显示该列表并不会将其从列表中删除并仍然显示。
看来,从“关注”部分中删除一个朋友并再次显示该列表之后,FirestoreService.shared...
之后,它只会返回而不会到达"Won't get here"
行。
每次打开FetchFriends()
时都会调用FriendsList
函数。
这是我所指的列表的图片,demouser
已从朋友列表中删除,但仍显示出来。
编辑:刚注意到,当我在列表中有多个用户时,它的确会被删除,并且可以按我的要求工作。当我只有一个用户(或列表中仅剩一个用户)时,它不会将其删除。
答案 0 :(得分:2)
fetchFriendList
永远不会使用nil
值调用回调:
var fetchedFriends: [Friend] = []
因此,您的else
分支是不必要的,完成处理程序可以是@escaping ([Friend]) -> Void
,没有可选项。
顺便说一句,您的方法也根本不调用completion
:
guard let results = doc?.data()?[USER_FOLLOWING] as? [String: Any] else { return }
通常,有很多不安全的地方。例如,当err
为nil
而doc
为nil
时,您的其他对象将在展开err!
时崩溃。
更好的选择:
guard err == nil, let doc = doc else {
print(err?.localizedDescription)
completion([])
return
}
let results = (doc.data()?[USER_FOLLOWING] as? [String: Any]) ?? [:]
let fetchedFriends = results.compactMap { result in
guard
let resultValue = result.value as? [String: Any],
let id = resultValue[FRIEND_ID] as? String,
let profilePic = resultValue[FRIEND_PROFILE_PIC] as? String,
let username = resultValue[FRIEND_NAME] as? String,
let email = resultValue[FRIEND_MAIL] as? String
else { return nil }
return Friend(id: id, profilePicture: profilePic, username: username, email: email)
}
completion(fetchedFriends)