In some cases when using Core Data in iOS and macOS apps more than one entity needs to be deleted. This post presents various examples of deleting multiple entities in Core Data with Swift:

  1. Delete Multiple Objects
  2. Delete Object With Relationship (Cascade Delete Rule)
  3. Delete Relationship Objects
  4. Delete Objects With Predicate
  5. Batch Delete
  6. Delete Everything (Delete All Objects, Reset Core Data)

Note: in this post persistentContainer will be used to refer to an initialized instance of NSPersistentContainer, and object will be used to refer to an initialized instance of NSManagedObject.

Delete Multiple Objects

One way to delete multiple objects in Core Data is to call delete(_:) on a NSManagedObjectContext for each NSManagedObject to delete, and then save the NSManagedObjectContext:

// List of multiple objects to delete
let objects: [NSManagedObject] = // A list of objects

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

// Delete multiple objects
for object in objects {
    context.delete(object)
}

// Save the deletions to the persistent store
try context.save()

Delete Object With Relationship (Cascade Delete Rule)

A Delete Rule defines what happens to relationship objects when an object is deleted, and a Cascade Delete Rule will delete relationship objects automatically when the parent object is deleted.

Set a Delete Rule on Entity Relationships inside of the Core Data Entity Inspector in Xcode:

Entity Inspector In Xcode Setting A Cascade Delete Rule

A Delete Rule will only take effect and consider relationships when an object is deleted. Setting a relationship to nil like object.items = nil or removing objects from a relationship will not trigger a Delete Rule.

Only deleting the parent object will trigger a Cascade Delete Rule:

let object = // An NSManagedObject

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

// Delete the object with a relationship. Calling
// delete(_:) will trigger the Delete Rules for
// object relationships
try context.delete(object)

// Save the deletions to the persistent store
try context.save()

Delete Relationship Objects

To delete relationship objects where a Cascade delete rule is not specified delete each relationship object individually then save the NSManagedObjectContext:

let object = // An NSManagedObject with a
// relationship called items

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

// Delete each related entity
for entity in object.items ?? [] {
    try context.delete(entity as? NSManagedObject)
}

// Save the deletions to the persistent store
try context.save()

Delete Objects With Predicate

Like deleting multiple objects in Core Data using delete(_:), delete objects with a predicate in Core Data by getting objects from a fetch request, deleting those objects, and then saving the NSManagedObjectContext:

// Create a fetch request with a predicate
let fetchRequest: NSFetchRequest<Business>
fetchRequest = Business.fetchRequest()

fetchRequest.predicate = // an NSPredicate

// Setting includesPropertyValues to false means
// the fetch request will only get the managed
// object ID for each object
fetchRequest.includesPropertyValues = false

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

// Perform the fetch request
let objects = try context.fetch(fetchRequest)
    
// Delete the objects
for object in objects {
    context.delete(object)
}

// Save the deletions to the persistent store
try context.save()

You can see more examples of fetch requests with predicates in the following article:

Swift Core Data String Queries
Learn how to find an exact string, regex search, and more in Core Data.

Batch Delete

Calling delete(_:) for each individual NSManagedObject may take time if there are many objects to delete. A faster approach to batch delete objects in Core Data is NSBatchDeleteRequest.

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]
)

Delete Everything (Delete All Objects, Reset Core Data)

One approach to delete everything and reset Core Data is to destroy the persistent store. Deleting and re-creating the persistent store will delete all objects in Core Data.

An important consideration when deleting everything in Core Data, make sure to release and re-initialize existing NSManagedObjectContext references. Using a NSManagedObjectContext backed by a deleted persistent store may have unexpected behavior.

// Get a reference to a NSPersistentStoreCoordinator
let storeContainer = 
    persistentContainer.persistentStoreCoordinator

// Delete each existing persistent store
for store in storeContainer.persistentStores {
    try storeContainer.destroyPersistentStore(
        at: store.url!,
        ofType: store.type,
        options: nil
    )
}

// Re-create the persistent container
persistentContainer = NSPersistentContainer(
    name: "CoreDataModelFile" // the name of 
    // a .xcdatamodeld file
)

// Calling loadPersistentStores will re-create the
// persistent stores
persistentContainer.loadPersistentStores { 
    (store, error) in
    // Handle errors
}

Batch Delete Core Data Objects in Swift

That's it! By using fetch requests, batch delete requests, managed object contexts, and persistent stores you can delete multiple objects and delete everything in Core Data using Swift.