0

I have View with a list of records from the CoreData entity and there is the following FetchRequest declared in the View

@FetchRequest(entity: Locations.entity(), sortDescriptors: [NSSortDescriptor(key: "locTimestamp", ascending: false)])
var locations: FetchedResults<Locations>

I have two functions for the deletion, one to delete just one record with the given ID

func deleteLocation(forID id: UUID) {
    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Locations")
    request.predicate = NSPredicate(format: "locID == %@", id as CVarArg)
    do {
        let location = try myContext.fetch(request) as! [NSManagedObject]
        myContext.delete(location.first!)
        try myContext.save()
    } catch let error {
        errTitle = "Error"
        errMessage = error.localizedDescription
        isError = true
    }
}

which works fine so List with records in View is refreshed and the second one for deletion of all records

func deleteAllLocations() {
    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Locations")
    let deleteRequest = NSBatchDeleteRequest(fetchRequest: request)
    do {
        try myContext.execute(deleteRequest)
        try myContext.save()
    } catch let error {
        errTitle = "Error"
        errMessage = error.localizedDescription
        isError = true
    }
}

which is executed (records deleted from CoreData entity) but List rows in View are not refreshed. What might be the issue here?

eXCore
  • 296
  • 2
  • 8
Dawy
  • 770
  • 6
  • 23

1 Answers1

1

Some googling reveals that batch deleting requires some more steps to work (info from here)

...

Some important considerations when using NSBatchDeleteRequest are:

  1. NSBatchDeleteRequest directly modifies the NSPersistentStore without loading any data into memory.
  2. An NSBatchDeleteRequest does not modify an NSManagedObjectContext. Use mergeChanges(fromRemoteContextSave:, into:) as shown in the example if needed to inform a NSManagedObjectContext of the batch delete.
// Specify a batch to delete with a fetch request
let fetchRequest: NSFetchRequest<NSFetchRequestResult>
fetchRequest = NSFetchRequest(entityName: "Business")

// Create a batch delete request for the
// fetch request
let deleteRequest = NSBatchDeleteRequest(
    fetchRequest: fetchRequest
)

// Specify the result of the NSBatchDeleteRequest
// should be the NSManagedObject IDs for the
// deleted objects
deleteRequest.resultType = .resultTypeObjectIDs

// Get a reference to a managed object context
let context = persistentContainer.viewContext

// Perform the batch delete
let batchDelete = try context.execute(deleteRequest)
    as? NSBatchDeleteResult

guard let deleteResult = batchDelete?.result
    as? [NSManagedObjectID]
    else { return }

let deletedObjects: [AnyHashable: Any] = [
    NSDeletedObjectsKey: deleteResult
]

// Merge the delete changes into the managed
// object context
NSManagedObjectContext.mergeChanges(
    fromRemoteContextSave: deletedObjects,
    into: [context]
)
eXCore
  • 296
  • 2
  • 8