我正在获取当前用户的朋友并将用户存储在一个数组中,该数组将显示在集合视图中。朋友集合视图位于我的主视图控制器上,这意味着始终保留在用户堆栈中。
我的问题是,如果用户通过用户个人资料页面添加或删除朋友,然后导航回主视图,我必须重新数据并刷新{{1}中的集合视图}}。这使得应用程序的数据成本很高,我肯定觉得这不是最有效的方式。
我知道Firebase允许我设置观察者,但是我不太确定如何在不接收大量数据的情况下做到这一点。
以下是我目前提取用户朋友的方式
viewWillAppear
这会在用户的func fetchFriends() {
let userID = Auth.auth().currentUser?.uid
var tempFriend = [UserClass]()
self.usersArray.removeAll()
collectionView.reloadData()
let friendRef = self.databaseRef.child("users").child(userID!).child("Friends")
friendRef.queryOrderedByKey().observe(.childAdded, with: { (snapshot) in
let friendID = "\(snapshot.value!)"
let usersRef = self.databaseRef.child("users")
usersRef.observeSingleEvent(of: .value, with: { (users) in
for user in users.children {
let friend = UserClass(snapshot: user as! DataSnapshot)
if friendID == friend.uid {
tempFav.append(friend)
}
}
self.usersArray = tempFav
self.collectionView.reloadData()
if self.usersArray.count == 0 {
self.noDataLabel.text = "You have no friends!"
self.noDataLabel.isHidden = false
} else {
self.noDataLabel.text = "Loading..."
self.noDataLabel.isHidden = true
}
})
})
}
为了使这个问题尽可能清晰,每次查看视图时,刷新用户朋友的最佳方法是什么,而无需再次获取整个列表。
答案 0 :(得分:3)
听起来你在视图消失时会删除你的观察者。此时,Firebase将从其内存缓存中删除用户数据。因此,当您在viewWillAppear
重新附加监听器时,需要从Firebase服务器重新加载数据。
如果您不想重新加载数据,则需要确保它在设备上仍然可用。有两种选择:
为确保数据保留在内存中,即使用户离开视图,您也必须保持观察者的连接。这意味着您将需要另一个类来管理观察者,该观察者在用户导航时不会删除观察者。
最简单的方法是拥有一个管理观察者和用户数据的全局单例,例如: UserDataManager
。当您的视图首次调用此类时,创建/附加侦听器并读取用户数据。当后续视图需要用户时,他们已经可以加载到UserDataManager
中以供使用。
这样做的主要问题是,当您为更多数据执行此操作时,最终可能会在内存中保留的数据超出所需数量。因此请注意这些不需要的数据的内存消耗,并根据需要修剪(删除侦听器)。
在应用启动时,减少下载数据量的一种简单方法是启用磁盘持久性(https://firebase.google.com/docs/database/ios/offline-capabilities#section-disk-persistence)。
如果启用了磁盘持久性,Firebase客户端会将最近观察到的数据存储到磁盘(除了将任何活动数据保留在内存中)。当您附加新观察者并且数据尚未在内存中时,Firebase将检查磁盘缓存中是否有该数据。如果数据存在于磁盘缓存中,它会使用它来重建其内存缓存并对服务器执行更便宜(带宽明智)的检查。