Home > database >  Update TableView based on dataset from server and local
Update TableView based on dataset from server and local

Time:10-03

I have a tableView which shows all the news, then if any of the news gets updates or new news are added I am checking and updating as follows. I am wondering if my approach is right and also looking for better options(tableviewdiffsource?)

Currently user sees the following 4 news in that order

[n1, n2, n3, n4]

when user pulls to refresh, he gets 3 news from server : [n4, n5, n6]

now I should display the news in this order [n4, n5, n6, n1, n2, n3]

var allNews = [News]()
func didFetchNews(newNews:[News]) {
    var news:[News] = newNews
    var newsSet = Set(newNews)

    var deletedPaths = [IndexPath]()

    for i in 0..<allNews.count {
       let news = allNews[i];
       if !newsSet.contains(news) {
         news.append(news)
       } else {
         deletedPaths.append(IndexPath(row: i, section: 0))
       }
    }

    var insertedPath = [IndexPath]()
    for i in 0..<newNews.count {
        insertedPath.append(IndexPath(row: i, section: 0))
    }

    self.tableView.beginUpdates()
    self.tableView.insertRows(at: insertedPath, with: .automatic)
    self.tableView.deleteRows(at: deletedPaths, with: .automatic)
    self.tableView.endUpdates()
}

CodePudding user response:

DiffableDataSource is probably the most efficient solution.

However your code can also be optimized by using higher level functions like filter and map.

First the indices of the updated news are calculated. As the new items are inserted on the top the insertion index paths are equal to the indices of the new items.

Then the items are removed at the filtered indices and the new items are inserted at index 0. reversed() avoids an out-of-range crash.

func didFetchNews(newNews: [News]) {
    let deletionIndices = allNews.indices.filter{newNews.contains(allNews[$0])}
    let deletionIndexPaths = deletionIndices.map{IndexPath(row: $0, section: 0)}
    let insertionIndexPaths = newNews.indices.map{IndexPath(row: $0, section: 0)}
    
    for index in deletionIndices.reversed() { allNews.remove(at: index) }
    allNews.insert(contentsOf: newNews, at: 0)

    self.tableView.beginUpdates()
    self.tableView.insertRows(at: insertionIndexPaths, with: .automatic)
    self.tableView.deleteRows(at: deletionIndexPaths, with: .automatic)
    self.tableView.endUpdates()
} 
  • Related