Еще на Если заявление Else не будет запущено, не могу понять почему - PullRequest
0 голосов
/ 17 октября 2019

У меня есть этот блок кода:

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 Ответ

2 голосов
/ 17 октября 2019

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...