我当前正在构建一个聊天应用程序,当我单击一个用户时,它将带我到聊天记录控制器。在这里,我在viewdidload()中调用了函数fetchChatMessages(),该函数实质上是从firestore中获取会话的。问题是,每当我转到上一个控制器并再次打开聊天时,它都会再次获取消息。
不确定是从缓存还是从服务器本身获取。但是我确实在每次打印的firestore提取代码下写了一条打印语句。
现在我是新手,所以我的问题是,在其他聊天应用程序中,您可以看到似乎只是从服务器提取了一次消息,然后添加了侦听器并更新了集合视图以显示新消息。消息。就我而言,似乎一切都一遍又一遍地获取。即使我已经添加了侦听器并遵循了广受好评的教程。
此外,无论何时获取消息,我都会在底部代码中添加滚动条,因此,每次获取新消息时,控制器都会自动滚动至底部。但这每次我打开聊天时都会发生。我正在尝试修复此错误,该错误使得控制器在每次出现视图时都会不断滚动,这让我感到奇怪,打开控制器时我是否一次又一次联系firebase?
override func viewDidLoad() {
super.viewDidLoad()
fetchCurrentUser()
fetchMessages()
setupLoadView()
}
// MARK:提取消息
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中一样保持在滚动位置。
答案 0 :(得分:2)
这里的问题是,每次离开屏幕时,控制器都会被释放,因为您可能将控制器推到堆栈上,然后将其弹出,这将擦除控制器的所有内部状态。这种行为确实是有意的(一旦屏幕加载,就会调用viewDidLoad)。您可以通过多种方式解决此问题。一种简单的方法是引入单例服务(在应用程序之间共享的服务),该服务包含控制器的状态,因此,每次创建控制器时,都会向服务询问其状态。请记住,这不是一个很好的解决方案,但是它应该足以作为起点。如果您需要一个示例,稍后我将相应地编辑Anwender。
答案 1 :(得分:0)
我无法就此给出确切的答案,因为它实际上取决于应用程序和服务器支持的功能,最终我将拥有某种数据库服务和聊天服务(不应通过单例访问这些服务)模式,而是通过依赖项注入)。当应获取数据时,聊天服务将定义某种策略,这意味着控制器不应意识到这一点。然后,聊天服务将通过数据库层将消息存储在一些持久性存储中,例如每个聊天的用户默认值,领域或核心数据。每次用户进入一个已经获取的聊天记录时,聊天服务都会检查是否有持久数据,如果没有,它将从服务器获取。