Сообщения чата извлекаются каждый раз, когда я открываю viewcontroller - PullRequest
2 голосов
/ 09 октября 2019

В настоящее время я создаю приложение чата, и когда я нажимаю на пользователя, оно переводит меня в контроллер журнала чата. Здесь я вызываю функцию fetchChatMessages () в viewdidload (), которая, по сути, извлекает разговор из firestore. Проблема в том, что всякий раз, когда я захожу на предыдущий контроллер и снова открываю чат, он снова получает сообщения.

Не уверен, идет ли выборка из кэша или с самого сервера. Но я написал заявление для печати под кодом извлечения в пожарном магазине, которое печатается каждый раз.

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

Кроме того, я добавил прокрутку до нижнего кода при каждом получении сообщений, поэтому каждый раз при получении нового сообщения контроллер автоматически прокручивает до нижнего уровня. ,Но это происходит каждый раз, когда я открываю чат. Я пытался исправить эту ошибку, когда контроллер продолжает прокручивать каждый раз, когда появляется представление, что заставляет меня задуматься, связываюсь ли я снова и снова с firebase при открытии контроллера?

override func viewDidLoad() {
    super.viewDidLoad()

    fetchCurrentUser()
    fetchMessages()
    setupLoadView()
}

// MARK: Fetch Messages

var listener: ListenerRegistration?

fileprivate func fetchMessages(){
    print("Fetching Messages")
    guard let cUid = Auth.auth().currentUser?.uid else {return}

    let query = Firestore.firestore().collection("matches").document(cUid).collection(connect.uid).order(by: "Timestamp")

    listener = query.addSnapshotListener { (querySnapshot, error) in
        if let error = error{
            print("There was an error fetching messages", error.localizedDescription)
            return
        }

        querySnapshot?.documentChanges.forEach({ (change) in
            if change.type == .added{
                let dictionary = change.document.data()
                self.items.append(.init(dictionary: dictionary))
                print("FIRESTORE HAS BEEN CONTACTED FETCHING MESSAGES")
            }
        })

        self.collectionView.reloadData()
        self.collectionView.scrollToItem(at: [0, self.items.count - 1], at: .bottom, animated: true)
        print("Fetched messages")
    }
}

//MARK: View Disappears

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

    if isMovingFromParent{
        listener?.remove()
    }
}

Я хочу, чтобы контроллер запомнил свое состояние. Например, если я прокручиваю сообщения, выхожу из контроллера и снова ввожу его, он остается в положении прокрутки, как в WhatsApp.

Ответы [ 2 ]

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

Проблема в том, что ваш контроллер освобождается каждый раз, когда вы покидаете экран, потому что вы, вероятно, помещаете контроллер в стек и вставляете его впоследствии, это стирает все внутреннее состояние контроллера. Это поведение действительно предназначено (viewDidLoad вызывается после загрузки экрана). Вы можете решить эту проблему несколькими способами. Легко было бы внедрить одноэлементную службу (службу, которая совместно используется приложением), которая хранит состояние контроллера, поэтому каждый раз, когда создается контроллер, он запрашивает у службы его состояние. Имейте в виду, что это не очень хорошее решение, но оно должно быть достаточным в качестве отправной точки. Если вам нужен пример, я позже отредактирую свой Anwender соответственно.

0 голосов
/ 10 октября 2019

Я не могу дать вам однозначного ответа на этот вопрос, потому что это действительно зависит от того, какие функции поддерживает приложение и сервер, в конце концов, у меня будет какая-то служба баз данных и службы чата (к ним не следует обращаться через синглтоншаблон, а скорее через внедрение зависимостей). Служба чата будет определять какую-то политику, когда данные должны быть получены, что означает, что контроллер не должен знать об этом. Затем служба чата будет хранить сообщения через слой базы данных в каком-то постоянном хранилище, например, по умолчанию для пользователя, области или основных данных для каждого чата. Каждый раз, когда пользователь входит в уже загруженный чат, служба чата будет проверять, доступны ли сохраненные данные, если нет, то будет извлекать их с сервера.

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