Swift Firebase观察.childAdded对现有项目而不是新项目的反应
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swift Firebase观察.childAdded对现有项目而不是新项目的反应相关的知识,希望对你有一定的参考价值。
我有一个裁判,我只想在添加新项目时收听(它位于下面的viewWillAppear
中)。添加新项目时,将显示newItemsButton。如果没有任何新内容添加到数据库中已有的内容,则该按钮不应出现。
问题是观察者一开始观察,即使没有添加任何新内容,newItemButton也会出现。 我在做什么错?
db:
-posts
-postId_1
-postId_2
-postId_3
代码:
var startKey: String?
let postsRef = Database.database().reference().child("posts")
let postsObserverRef = Database.database().reference().child("posts")
override func viewDidLoad() {
super.viewDidLoad()
paginate()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
listenForNewItems()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
postsObserverRef.removeAllObservers()
}
func listenForNewItems() {
postsObserverRef.observe(.childAdded) { (snapshot) in
let postId = snapshot.key
let isContained = self.dataSource.contains { $0.postId == postId }
if !isContained {
// show newItemsButton
}
}
}
func paginate() {
if startKey == nil {
postsRef.queryOrderedByKey().queryLimited(toLast: 20)
.observeSingleEvent(of: .value, with: { (snapshot) in
// fill datasource
})
} else {
postsRef.queryOrderedByKey().queryEnding(atValue: startKey).queryLimited(toLast: 21)
.observeSingleEvent(of: .value, with: { (snapshot) in
// fill datasource
})
}
}
答案
阅读完之后,无论如何,.observe(.childAdded)似乎总是会触发至少一次。我对代码做了一些调整。这似乎是聆听新项目的不必要的长途之路,但这肯定可以消除我最初遇到的问题。我会接受任何更好的答案。
var lastPostId: String?
let postsObserverRef = Database.database().reference().child("posts")
override func viewDidLoad() {
super.viewDidLoad()
paginate()
getLastPostIdForNewItems()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// I added this 1 sec wait here only to make sure the getLastPostIdForNewItems() in viewDidLoad finishes first. When switching tabs or pushing on/off child vcs the 1 sec won't make any difference
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.listenForNewItems(key: self.lastPostId)
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
removeNewItemsObserver()
}
func getLastPostIdForNewItems() {
postsObserverRef.queryLimited(toLast: 1).observeSingleEvent(of: .value) { (snapshot) in
guard let childSnapshot = snapshot.children.allObjects.first as? DataSnapshot else {
return
}
guard let dict = childSnapshot.value as? [String: Any] else { return }
guard let lastPostId = dict["postId"] as? String else { return }
self.lastPostId = lastPostId
self.listenForNewItems(key: lastPostId)
}
}
func listenForNewItems(key: String?) {
if let lastPostId = key {
postsObserverRef
.queryOrderedByKey()
.queryStarting(atValue: lastPostId)
.observe(.childAdded) { (snapshot) in
var postIds = [String]()
if let dict = snapshot.value as? [String: Any], let postId = dict["postId"] as? String {
postIds.append(postId)
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.005) {
guard let lastPostId = postIds.last else { return }
let isContained = self.dataSource.contains { $0.postId == lastPostId }
if !isContained {
self.lastPostId = lastPostId
// showNewItemsButton
}
}
}
} else {
postsObserverRef.observe(.childAdded) { (snapshot) in
var postIds = [String]()
if let dict = snapshot.value as? [String: Any], let postId = dict["postId"] as? String {
postIds.append(postId)
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.005) {
guard let lastPostId = postIds.last else { return }
let isContained = self.dataSource.contains { $0.postId == lastPostId }
if !isContained {
self.lastPostId = lastPostId
// showNewItemsButton
}
}
}
}
}
func removeNewItemsObserver() {
if let lastPostId = lastPostId {
postsObserverRef
.queryOrderedByKey()
.queryStarting(atValue: lastPostId)
.removeAllObservers()
} else {
postsObserverRef.removeAllObservers()
}
}
以上是关于Swift Firebase观察.childAdded对现有项目而不是新项目的反应的主要内容,如果未能解决你的问题,请参考以下文章
Swift,FIrebase - 无法通过 removeAllObservers 删除观察者