否则,如果不触发其他语句,则无法理解为什么

时间:2019-10-17 16:40:57

标签: swift

我有这段代码:

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已从朋友列表中删除,但仍显示出来。

enter image description here

编辑:刚注意到,当我在列表中有多个用户时,它的确会被删除,并且可以按我的要求工作。当我只有一个用户(或列表中仅剩一个用户)时,它不会将其删除。

1 个答案:

答案 0 :(得分:2)

fetchFriendList永远不会使用nil值调用回调:

var fetchedFriends: [Friend] = []

因此,您的else分支是不必要的,完成处理程序可以是@escaping ([Friend]) -> Void,没有可选项。

顺便说一句,您的方法也根本不调用completion

guard let results = doc?.data()?[USER_FOLLOWING] as? [String: Any] else { return }

通常,有很多不安全的地方。例如,当errnildocnil时,您的其他对象将在展开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)