Загрузить новые сообщения Swift 4.2 & Firebase - PullRequest
0 голосов
/ 18 февраля 2019

Я создал систему обмена сообщениями для своего приложения и разбиваю страницы на страницы в журнале чата, но у меня возникла проблема, заключающаяся в том, что, если новое сообщение отправлено, пользователю придется покинуть экран и снова открыть контроллер для просмотра.новые сообщения, которые они отправили / получили.Я попытался перезагрузить представление коллекции и снова просмотреть сообщения без удачи.Любая помощь приветствуется.

Наблюдение за сообщениями.С пагинацией. (работает отлично! При начальной загрузке.)

var messages =  [Message]()
fileprivate func observeMessages() {

    guard let uid = Auth.auth().currentUser?.uid else { return }
    guard let userId = user?.uid else { return }

    if currentKey == nil {

        let userMessageRef = Database.database().reference().child("user-message").child(uid).child(userId).queryLimited(toLast: 10).observeSingleEvent(of: .value) { (snapshot) in

            guard let first = snapshot.children.allObjects.first as? DataSnapshot else { return }
            guard var allObjects = snapshot.children.allObjects as? [DataSnapshot] else { return }

            allObjects.forEach({ (snapshot) in

                let messageId = snapshot.key

                let ref = Database.database().reference().child("messages").child(messageId)
                ref.observe(.value, with: { (snapshot) in

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

                    let message = Message(dictionary: dict)

                    self.messages.append(message)
                    self.messages.sort(by: { (message1, message2) -> Bool in
                        return message1.timeStamp.compare(message2.timeStamp) == .orderedDescending
                    })
                    self.collectionView?.reloadData()
                })
            })

            self.currentKey = first.key
        }

    } else {

        let userMessageRef = Database.database().reference().child("user-message").child(uid).child(userId).queryOrderedByKey().queryEnding(atValue: self.currentKey).queryLimited(toLast: 4).observeSingleEvent(of: .value) { (snapshot) in

            guard let first = snapshot.children.allObjects.first as? DataSnapshot else { return }
            guard var allObjects = snapshot.children.allObjects as? [DataSnapshot] else { return }

            allObjects.forEach({ (snapshot) in

                if snapshot.key != self.currentKey {

                    let messageId = snapshot.key

                    let ref = Database.database().reference().child("messages").child(messageId)
                    ref.observe(.value, with: { (snapshot) in
                        guard let dict = snapshot.value as? [String: Any] else { return }

                        let message = Message(dictionary: dict)

                        self.messages.append(message)
                        self.messages.sort(by: { (message1, message2) -> Bool in
                            return message1.timeStamp.compare(message2.timeStamp) == .orderedDescending
                        })
                        self.collectionView?.reloadData()
                    })
                }
            })
            self.currentKey = first.key

        }
    }
}

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Способ, которым я настроил мой, состоял в том, чтобы вызвать функцию в viewDidLoad, а затем снова в viewDidAppear.Я все еще учусь, но вы можете попробовать это, вероятно, это будет выглядеть примерно так:

override func viewDidLoad() {
    super.viewDidLoad()

    observeMessages(for: userID) { (messages) in
        self.messages = messages
        self.collectionView.reloadData()
    }
}

И снова в viewDidAppear:

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

    observeMessages(for: userID) { (messages) in
        self.messages = messages
        self.collectionView.reloadData()
    }
}
0 голосов
/ 18 февраля 2019

Из документации базы данных Firebase

В некоторых случаях вы можете захотеть вызвать обратный вызов один раз, а затем немедленно удалить его, например, при инициализации элемента пользовательского интерфейса, который вы не используете.не ожидаю перемен.Чтобы упростить этот сценарий, вы можете использовать метод Наблюдать за одиночным событиемOfType: обратный вызов события добавляется один раз, а затем снова не запускается..

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...