我正在获取当前用户的朋友并将用户存储在一个数组中,该数组将显示在集合视图中 . 朋友集合视图在我的家庭视图控制器上,这意味着它 always remains in the users stack .
我的问题是,如果用户通过用户 Profiles 页面添加或删除朋友,然后导航回主视图,我必须 refetch 数据并刷新 viewWillAppear
中的集合视图 . 这使得应用程序的数据成本高昂,我绝对觉得这不是最有效的方式 .
我知道Firebase允许我设置观察者,但是我不太确定如何在不接收大量数据的情况下做到这一点 .
这是我目前获取用户朋友的方式
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
}
})
})
}
这会在用户的 viewWillAppear
中调用
为了使这个问题尽可能清楚,每次查看视图时,刷新用户朋友的最佳方法是什么,而无需再次获取整个列表 .
1 回答
听起来你在视图消失时会删除你的观察者 . 此时,Firebase将从其内存缓存中删除用户数据 . 因此,当您在
viewWillAppear
中重新附加侦听器时,需要从Firebase服务器重新加载数据 .如果您不希望重新加载数据,则需要确保它在设备上仍然可用 . 有两种选择:
确保数据保留在内存中
确保数据持久保存到磁盘
确保数据保留在内存中
为确保数据保留在内存中,即使用户导航远离视图,也必须保持观察者的连接 . 这意味着您将需要另一个类来管理观察者,该观察者在用户导航时不会删除观察者 .
对此最简单的方法是拥有一个管理观察者和用户数据的全局单例,例如:
UserDataManager
. 当您的视图首次调用此类时,创建/附加侦听器并读取用户数据 . 当后续视图需要用户时,它们已经可以在UserDataManager
中加载以备使用 .这样做的主要问题是,当您为更多数据执行此操作时,最终可能会在内存中保留比所需数据更多的数据 . 因此请注意这些不需要的数据的内存消耗,并根据需要修剪(删除侦听器) .
确保数据持久保存到磁盘
应用程序启动时,减少下载数据量的一种简单方法是“启用磁盘持久性”(https://firebase.google.com/docs/database/ios/offline-capabilities#section-disk-persistence) .
如果启用了磁盘持久性,Firebase客户端会将最近观察到的数据存储到磁盘(除了将任何活动数据保留在内存中) . 当您附加新观察者并且数据尚未在内存中时,Firebase将检查磁盘缓存中是否有该数据 . 如果数据存在于磁盘高速缓存中,它将使用它来重建其内存高速缓存并对服务器执行更便宜(带宽明智)的检查 .