简体   繁体   中英

Swift Firebase: UIRefreshControl with .childAdded

Ok, pls pardon me if this might be a very elementary question, but how do I refresh my tableView with only new items added to Firebase?

I am trying to implement a 'pull to refresh' for my tableView and populate my tableView with new items that have been added to Firebase. At viewDidLoad, I call .observeSingleEvent(.value) to display the table.

At the refresh function, I call .observe(.childAdded). However doing so will make the app consistently listen for things added, making my app consistently reloadingData. How do I code it such that it only refreshes when I do the 'pull to refresh'? My code so far:

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)

        }
    }

I also attempted observeSingleEvent(.childAdded) but it only pulls out one single entry (the very top entry) from Firebase.

I am not sure if my approach is correct in the first place. Any advice here pls, thanks.

Add

var lastKey: String? = nil

In the loop where you iterate over the children set the lastKey to the current snap's key.

lastKey = snap.key

Let me know if this works for you.

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)

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM