Here’s an example:

let batchDeleteFetchRequest = NSFetchRequest(entityName: "Thing")
batchDeleteFetchRequest.sortDescriptors = [NSSortDescriptor(key: "uri", ascending: true)]
batchDeleteFetchRequest.predicate = NSPredicate(format: "NOT (uri IN %@)", URIsInDataDump)
let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: batchDeleteFetchRequest)
do {
    try managedObjectContext.executeRequest(batchDeleteRequest)
} catch {


There isn’t much official documentation out there because NSBatchDeleteRequest doesn’t exist in documentation, only a video clip from Core Data’s spotlight at WWDC.

Anyway, when running the above code and watching the context, you’ll notice no changes were acknowledged, though loading a new fetch does show the items were deleted. What?

Well, NSBatchDeleteRequest works by deleting directly from the store and even though it’s the managedObjectContext executing the request, it happens outside of its knowledge and therefore, isn’t aware of the persistent store change.

This means that iCloud Core Data won’t update, and even trivial things like NSFetchedResultsController won’t fire off changes. One interaction I’m unsure of is how it interacts with parent contexts – so stay tuned for a little test into that later!

Posted in iOS