cannyboy
cannyboy

Reputation: 24426

How to search thru Core Data entities and delete certain objects

I'm unclear how to remove certain objects from Core Data database. I think I've got it working so I can find the objects, but don't know how to delete them from Core Data. In this example I'm searching the entity News for items which have expired. I use the 'expires' property (an int 32 unix time stamp) and see if the number is less than the current unix time stamp. Not sure if the NSPredicate is right in this.

NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"News" inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity]; 

// Set up predicate here?
NSPredicate *pred = [NSPredicate predicateWithFormat:@"expires < %i", dateInt]; // dateInt is a unix time stamp for the current time
[request setPredicate:predicate];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"forename" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];
NSError *error;
NSMutableArray *mutableFetchResults = [[[managedObjectContext executeFetchRequest:request error:&error] mutableCopy] autorelease];
[request release];

// delete the found objects here?

Upvotes: 1

Views: 5478

Answers (2)

Inder Kumar Rathore
Inder Kumar Rathore

Reputation: 39988

You can use NSBatchDeleteRequest available on iOS 9.0+, macOS 10.11+, tvOS 9.0+, watchOS 2.0+

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"expires < %i", dateInt];
NSFetchRequest *fetchRequest = [News fetchRequest];
[fetchRequest setPredicate:predicate];
// Create batch delete request
NSBatchDeleteRequest *deleteReq = [[NSBatchDeleteRequest alloc] initWithFetchRequest:fetchRequest];
NSError *error = nil;
NSBatchDeleteResult *deletedResult = [appDelegate.persistentContainer.viewContext executeRequest:deleteReq error:&error];
if (error) {
  NSLog(@"Unable to delete the data");
}
else {
  NSLog(@"%@ deleted", deleteReq.result);
}

Swift code (from the above link)

let fetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Employee")
fetch.predicate = NSPredicate(format: "terminationDate < %@", NSDate())
let request = NSBatchDeleteRequest(fetchRequest: fetch)

do {
    let result = try moc.execute(request)
} catch {
    fatalError("Failed to execute request: \(error)")
}

NOTE:

I found below comment about execute of moc

Method to pass a request to the store without affecting the contents of the managed object context.

Which means any unsaved data in moc won't be affected. i.e. if you've created/updated entity that falls in the delete request criteria and don't called save on moc then that object won't be deleted.

Upvotes: 0

Ole Begemann
Ole Begemann

Reputation: 135548

Call -[NSManagedObjectContext deleteObject:] for every object you want to delete, then commit the changes.

Upvotes: 2

Related Questions