Swift Firebase -Как добавить наблюдателя в viewDidLoad, удалить его в viewDidDisappear, а затем снова прочитать его в viewWillAppear? - PullRequest
0 голосов
/ 14 апреля 2019

У меня есть журнал чата, и сначала мой .observe( .childAdded) слушатель вызвал viewDidLoad и удалил его в viewDidDisappear, но после прочтения этого комментария enter image description here из этого вопроса Я переместил слушателя на viewWillAppear, и теперь всякий раз, когда я переключаю представления и возвращаюсь, слушатель запускается снова и мои tableData заполняется одной и той же информацией дважды.

Например.скажем, у меня есть только 1 сообщение в чате от другого пользователя, который говорит "привет".Если vc чата находится в tabTwo, то при первом появлении vc будет запущен код, и у источника данных collectionView будет 1 сообщение с надписью «hello».Если я нажму другую вкладку и вернусь к tabTwo, теперь появятся 2 сообщения, которые говорят «привет» (то же самое точное сообщение), потому что код повторяется снова и снова.Это становится серьезной проблемой, если есть 100 сообщений.Это означает, что будет 200 сообщений, и они будут складываться каждый раз, когда я переключаю вкладки и возвращаюсь.

Должен ли я также очистить tableData и перезагрузить collectionView в viewDidDisappear, когда я удаляю наблюдателя, чтобывсе данные не дублируются при повторном вызове viewWillAppear?Это то, что я сделал, чтобы решить проблему, но это кажется неправильным.

Есть ли лучший способ вызвать наблюдателя в viewDidLoad, а затем снова прочитать его в viewWillAppear, не вызывая дублирование данных моим collectionView?

let currentUserId = Auth.auth().currentUser?.uid!
let toId = "theOtherUsersId"

var tableData = [Message]()
let ref = Database.database().reference().child("messageIds")

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    ref.child(currentUserId).child(toId).observe( .childAdded, with: { [weak self] (snapshot) in

        let messageId = snapshot.key

        self?.getMessagesWith(messageId)
    })
}

func getMessagesWith(_ messageId: String) {

    Database.database().reference().child("messages").child(messageId).observeSingleEvent(of: .value, with: { [weak self] (snapshot) in

        guard let dict = snapshot.value as? [String: Any] else { return }

        let message = Message(dict: dict)

        self?.tableData.append(message)
        self?.collectionView.reloadData()
    })
}

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)

    tableData.removeAll() // something seems wrong about doing this
    collectionView.reloadData()
    ref.removeAllObservers()
}

1 Ответ

0 голосов
/ 14 апреля 2019

@ GaloTorresSevilla комментарии под моим первоначальным ответом были правильными.Он предложил переместить наблюдателя в viewWillAppear и просто использовать messageId, чтобы отфильтровать любые сообщения, которые уже существуют в tableData.Он был на 100% прав, потому что когда я возвращаюсь на вкладку, никакие данные не дублируются

let currentUserId = Auth.auth().currentUser?.uid!
let toId = "theOtherUsersId"

var tableData = [Message]()
let ref = Database.database().reference().child("messageIds")

override func viewDidLoad() {
    super.viewDidLoad()
    // nothing to do here
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    ref.child(currentUserId).child(toId).observe( .childAdded, with: { [weak self] (snapshot) in

        let messageId = snapshot.key

        // in viewWillAppear if the tableData contains the messageId above then return
        if self.tableData.contains (where: { $0.messageId ?? “” == messageId }) {
            return
        }
        self?.getMessagesWith(messageId)
    })
}

func getMessagesWith(_ messageId: String) {

    Database.database().reference().child("messages").child(messageId).observeSingleEvent(of: .value, with: { [weak self] (snapshot) in

        guard let dict = snapshot.value as? [String: Any] else { return }

        let message = Message(dict: dict)

        self?.tableData.append(message)
        self?.collectionView.reloadData()
    })
}

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)

    ref.child(currentUserId).child(toId).removeAllObservers()
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...