remove duplicates in coredata and automatically update in tableview in swift

To remove duplicates in CoreData and automatically update in TableView, we need to use NSFetchedResultsController.

First, we need to create a fetch request where we set the "resultType" to "dictionaryResultType" and also set the "propertiesToFetch" array with the attributes you want to fetch. Then we use the "NSExpression" to get distinct value(s) for that column.

Secondly, we need to implement an NSFetchedResultsControllerDelegate to monitor any changes to the data and reload the tableview accordingly.

Here's the example code:

main.swift
// create the fetch request
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "EntityName")
fetchRequest.resultType = .dictionaryResultType
fetchRequest.propertiesToFetch = ["attributeName"]
fetchRequest.returnsDistinctResults = true
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "attributeName", ascending: true)]

// execute the fetch request
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
fetchedResultsController.delegate = self
do {
    try fetchedResultsController.performFetch()
} catch {
    print(error)
}

// implement the NSFetchedResultsControllerDelegate
extension ViewController: NSFetchedResultsControllerDelegate {
    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        tableView.reloadData()
    }
}

// display the results in the tableview
override func numberOfSections(in tableView: UITableView) -> Int {
    return fetchedResultsController.sections?.count ?? 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return fetchedResultsController.sections?[section].numberOfObjects ?? 0
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
    let object = fetchedResultsController.object(at: indexPath) as! NSManagedObject
    cell.textLabel?.text = object.value(forKey: "attributeName") as? String
    return cell
}
1620 chars
39 lines

Note: Replace "EntityName" with the name of your entity and "attributeName" with the name of the attribute you want to fetch distinct values for.

gistlibby LogSnag