Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Core Data: Quickest way to delete all instances of an entity

I'm using Core Data to locally persist results from a Web Services call. The web service returns the full object model for, let's say, "Cars" - could be about 2000 of them (and I can't make the Web Service return anything less than 1 or ALL cars.

The next time I open my application, I want to refresh the Core Data persisted copy by calling the Web Service for all Cars again, however to prevent duplicates I would need to purge all data in the local cache first.

Is there a quicker way to purge ALL instances of a specific entity in the managed object context (e.g. all entities of type "CAR"), or do I need to query them call, then iterate through the results to delete each, then save?

Ideally I could just say delete all where entity is Blah.

like image 636
Adaromas Avatar asked Sep 05 '09 15:09

Adaromas


People also ask

What is Nsmanagedobjectcontext?

An object space to manipulate and track changes to managed objects.

What is Core Data transformable?

When you declare a property as Transformable Core Data converts your custom data type into binary Data when it is saved to the persistent store and converts it back to your custom data type when fetched from the store. It does this through a value transformer.

What is Nsfetchrequest in Swift?

A description of search criteria used to retrieve data from a persistent store.

What is relationship in Core Data?

Inverse relationships enable Core Data to propagate change in both directions when an instance of either the source or destination type changes. Every relationship must have an inverse. When creating relationships in the Graph editor, you add inverse relationships between entities in a single step.


1 Answers

iOS 9 and later:

iOS 9 added a new class called NSBatchDeleteRequest that allows you to easily delete objects matching a predicate without having to load them all in to memory. Here's how you'd use it:

Swift 5

let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Car") let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)  do {     try myPersistentStoreCoordinator.execute(deleteRequest, with: myContext) } catch let error as NSError {     // TODO: handle the error } 

Objective-C

NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Car"]; NSBatchDeleteRequest *delete = [[NSBatchDeleteRequest alloc] initWithFetchRequest:request];  NSError *deleteError = nil; [myPersistentStoreCoordinator executeRequest:delete withContext:myContext error:&deleteError]; 

More information about batch deletions can be found in the "What's New in Core Data" session from WWDC 2015 (starting at ~14:10).

iOS 8 and earlier:

Fetch 'em all and delete 'em all:

NSFetchRequest *allCars = [[NSFetchRequest alloc] init]; [allCars setEntity:[NSEntityDescription entityForName:@"Car" inManagedObjectContext:myContext]]; [allCars setIncludesPropertyValues:NO]; //only fetch the managedObjectID  NSError *error = nil; NSArray *cars = [myContext executeFetchRequest:allCars error:&error]; [allCars release]; //error handling goes here for (NSManagedObject *car in cars) {   [myContext deleteObject:car]; } NSError *saveError = nil; [myContext save:&saveError]; //more error handling here 
like image 57
Dave DeLong Avatar answered Oct 14 '22 16:10

Dave DeLong