Swift Firebase:带有 .childAdded 的 UIRefreshControl

Posted

技术标签:

【中文标题】Swift Firebase:带有 .childAdded 的 UIRefreshControl【英文标题】:Swift Firebase: UIRefreshControl with .childAdded 【发布时间】:2017-03-05 10:45:31 【问题描述】:

好的,如果这可能是一个非常基本的问题,请原谅我,但是如何刷新我的 tableView 只添加新项目到 Firebase?

我正在尝试为我的 tableView 实施“拉动刷新”,并使用已添加到 Firebase 的新项目填充我的 tableView。在 viewDidLoad 中,我调用 .observeSingleEvent(.value) 来显示表格。

在刷新函数中,我调用了 .observe(.childAdded)。但是,这样做会使应用程序始终监听添加的内容,从而使我的应用程序始终重新加载数据。如何对其进行编码,使其仅在我执行“拉动刷新”时才刷新?到目前为止我的代码:

lazy var refresh: UIRefreshControl = 
        let refresh = UIRefreshControl(frame: CGRect(x: 50, y: 100, width: 20, height: 20))
        refresh.addTarget(self, action: #selector(refreshData), for: .valueChanged)
        return refresh
    ()

var eventsArray: [FIRDataSnapshot]! = []

    override func viewDidLoad() 
        super.viewDidLoad()
        ref = FIRDatabase.database().reference()

        ref.child("events").observeSingleEvent(of: .value, with:  (snapshot) in
            for snap in snapshot.children 
                self.eventsArray.insert(snap as! FIRDataSnapshot, at: 0)
            
            DispatchQueue.main.async 
                self.tableView.reloadData()
            

        )  (error) in
            print(error.localizedDescription)

        
    

    func refreshData() 
        self.eventsArray = []

        ref.child("events").observe(.childAdded, with:  (snapshot) in
            print(snapshot)
            self.eventsArray.insert(snapshot, at: 0)
            DispatchQueue.main.async 
                self.refresh.endRefreshing()
                self.tableView.reloadData()
            
        )  (error) in
            print(error.localizedDescription)

        
    

我也尝试过 observeSingleEvent(.childAdded) 但它只从 Firebase 中提取一个条目(最顶部的条目)。

首先我不确定我的方法是否正确。任何建议请在这里,谢谢。

【问题讨论】:

【参考方案1】:

添加

var lastKey: String? = nil

在遍历子项的循环中,将 lastKey 设置为当前快照的键。

lastKey = snap.key

让我知道这是否适合你。

func refreshData() 
    // Make sure you write a check to make sure lastKey isn't nil
    ref.child("events").orderByKey().startAt(lastKey).observeSingleEvent(of: .value, with:  (snapshot) in
        // You'll have to get rid of the first childsince it'll be a duplicate, I'm sure you can figure that out.
        for snap in snapshot.children 
            self.eventsArray.insert(snap as! FIRDataSnapshot, at: 0)
        
        DispatchQueue.main.async 
            self.refresh.endRefreshing()
            self.tableView.reloadData()
        
    )  (error) in
        print(error.localizedDescription)

    

【讨论】:

您好,虽然上述方法有效,但从长远来看可能不可持续。如果用户要删除事件,结果发现 laskKey 被删除,这将导致应用程序崩溃。有没有更好的方法来解决这个问题? 是否会导致应用崩溃?我相当肯定它不会返回任何结果,或者只是跳过那个键,不过我可能是错的。你测试了吗? 是的,我刚刚测试过。但是我设法解决了它,因为它在我试图删除重复的孩子的那一行崩溃了。话虽如此,它仍然会导致应用程序不显示最新的事件集,即将数据库与 tableView 进行比较。用户可以删除和创建事件,因此数据库可以是非常动态的。似乎重新创建整个 tableView 可能是一个更可持续的解决方案? 授予但你不能只使用你在 viewDidLoad() 中使用的方法,并且每次“刷新”时都简单地重用它吗?

以上是关于Swift Firebase:带有 .childAdded 的 UIRefreshControl的主要内容,如果未能解决你的问题,请参考以下文章

使用 Swift 从带有条件的 Firebase 数据库中获取数据

Swift 3 数据从主控制器到带有 Firebase 和 segue 的视图控制器

Firebase Analytics for iOS — 带有预定义事件的自定义参数 (Swift)

如何在swift ui中使用autoid将带有字段的新文档添加到firebase集合

致命错误:索引超出范围 - Swift 3 和 Firebase

Xcode 11.4 Objective-C 语言的快速帮助,而不是 swift 语言,用于带有 Cocoapods 的 firebase API(iOS 13.4 应用程序)