Ler Ws Ler Ws - 3 months ago 24
Swift Question

How to ensure that the data is not retrieved and appended as a whole each time a new entry is added?

func generateDataForRecents() {
if URLArrayStringThisSeason.count == 0 {
self.activityIndicator2.isHidden = false

let databaseRef = FIRDatabase.database().reference()

databaseRef.child("palettes").queryLimited(toFirst: 100).observe(.value, with: { (snapshot) in

if let snapDict = snapshot.value as? [String:AnyObject]{

for each in snapDict as [String:AnyObject]{

let URL = each.value["URL"] as! String



//let pictureTitle = each.value["title"] as! String

self.whatsNewCollectionView?.reloadData() //Reloads data after the number and all the URLs are fetched
self.activityIndicator2.isHidden = true


The following code does a retrieval of data each time the function is called, or when a new data is added.

This is extremely useful when the app is first started up or closed and then restarted. However, when the app is running, whenever a new entry is added, the code seemed to run again and thus appending twice the amount of new data.

For example, when there are already 15 entries identified and then suddenly a new entry is added, the array of the URL would contain 15+16 thus amounting to a total of 31.

How do I make it such that the new data is added to the array instead of adding the entire snapshot in?


You do that by listening for .childAdded events, instead of listening for .value:

var query = databaseRef.child("palettes").queryLimited(toFirst: 100)
query.observe(.childAdded, with: { (snapshot) in
    let URL = snapshot.childSnapshot(forPath/: "URL").value as! String

Since you have a limit-query, adding a 101st item means that one item will be removed from the view. So you'll want to handle .childRemoved too:

query.observe(.childRemoved, with: { (snapshot) in 
    // TODO: remove the item from snapshot.key from the araay

I recommend that you spend some time in the relevant documentation on handling child events before continuing.