Core Data
iOS development
data management
app development
Swift

Delete/Reset all entries in Core Data?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Deleting all entries in Core Data can be done with NSBatchDeleteRequest (fastest, bypasses object graph), fetch-and-delete loops (safe with relationships), or destroying the entire persistent store (nuclear reset). The right approach depends on your use case: batch delete for clearing specific entities, fetch-and-delete when cascade rules matter, and store destruction for a full factory reset. This article covers all three methods with Swift examples.

swift
1import CoreData
2
3func deleteAllEntities(_ entityName: String, context: NSManagedObjectContext) {
4    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
5    let batchDelete = NSBatchDeleteRequest(fetchRequest: fetchRequest)
6    batchDelete.resultType = .resultTypeObjectIDs
7
8    do {
9        let result = try context.execute(batchDelete) as? NSBatchDeleteResult
10        let objectIDs = result?.result as? [NSManagedObjectID] ?? []
11
12        // Merge changes into the in-memory context
13        let changes = [NSDeletedObjectsKey: objectIDs]
14        NSManagedObjectContext.mergeChanges(
15            fromRemoteContextSave: changes,
16            into: [context]
17        )
18        print("Deleted \(objectIDs.count) \(entityName) objects")
19    } catch {
20        print("Batch delete failed: \(error)")
21    }
22}
23
24// Usage
25deleteAllEntities("User", context: persistentContainer.viewContext)
26deleteAllEntities("Order", context: persistentContainer.viewContext)

NSBatchDeleteRequest operates directly on the persistent store, bypassing the managed object context. This makes it fast but requires merging changes back into the context to keep in-memory objects in sync.

Method 2: Delete All Entities in the Model

swift
1func deleteAllData(context: NSManagedObjectContext) {
2    let entityNames = context.persistentStoreCoordinator?.managedObjectModel.entities.compactMap { $0.name } ?? []
3
4    for entityName in entityNames {
5        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
6        let batchDelete = NSBatchDeleteRequest(fetchRequest: fetchRequest)
7
8        do {
9            try context.execute(batchDelete)
10        } catch {
11            print("Failed to delete \(entityName): \(error)")
12        }
13    }
14
15    // Save and reset the context
16    do {
17        try context.save()
18    } catch {
19        print("Save failed: \(error)")
20    }
21
22    context.reset()
23}

Iterating through all entities in the managed object model ensures everything is cleared without hardcoding entity names.

Method 3: Fetch and Delete (Relationship-Safe)

swift
1func fetchAndDeleteAll(_ entityName: String, context: NSManagedObjectContext) {
2    let fetchRequest: NSFetchRequest<NSManagedObject> = NSFetchRequest(entityName: entityName)
3
4    do {
5        let objects = try context.fetch(fetchRequest)
6        for object in objects {
7            context.delete(object)
8        }
9        try context.save()
10        print("Deleted \(objects.count) \(entityName) objects")
11    } catch {
12        print("Fetch and delete failed: \(error)")
13    }
14}

Fetch-and-delete loads objects into memory and deletes them one by one. This is slower than batch delete but respects cascade delete rules and triggers NSManagedObjectContextObjectsDidChange notifications.

Method 4: Destroy the Persistent Store (Full Reset)

swift
1func destroyPersistentStore(container: NSPersistentContainer) {
2    guard let storeURL = container.persistentStoreCoordinator
3        .persistentStores.first?.url else { return }
4
5    let coordinator = container.persistentStoreCoordinator
6
7    do {
8        // Destroy the store file
9        try coordinator.destroyPersistentStore(
10            at: storeURL,
11            ofType: NSSQLiteStoreType,
12            options: nil
13        )
14
15        // Recreate it empty
16        try coordinator.addPersistentStore(
17            ofType: NSSQLiteStoreType,
18            configurationName: nil,
19            at: storeURL,
20            options: nil
21        )
22        print("Store destroyed and recreated")
23    } catch {
24        print("Failed to reset store: \(error)")
25    }
26}

This deletes the SQLite file and recreates an empty one. It is the fastest way to reset everything but loses all data including metadata.

Method 5: Delete the SQLite File Directly

swift
1func deleteSQLiteFiles(container: NSPersistentContainer) {
2    guard let storeURL = container.persistentStoreCoordinator
3        .persistentStores.first?.url else { return }
4
5    let coordinator = container.persistentStoreCoordinator
6
7    // Remove the store from the coordinator first
8    for store in coordinator.persistentStores {
9        try? coordinator.remove(store)
10    }
11
12    // Delete all SQLite files
13    let fileManager = FileManager.default
14    let storePath = storeURL.path
15    let relatedFiles = [storePath, storePath + "-wal", storePath + "-shm"]
16
17    for file in relatedFiles {
18        try? fileManager.removeItem(atPath: file)
19    }
20
21    // Re-add the store
22    try? coordinator.addPersistentStore(
23        ofType: NSSQLiteStoreType,
24        configurationName: nil,
25        at: storeURL,
26        options: nil
27    )
28}

SQLite uses WAL (Write-Ahead Logging) files (-wal and -shm). Delete all three files to ensure a clean reset.

With Predicate (Conditional Delete)

swift
1// Delete only objects matching a condition
2func deleteWhere(_ entityName: String, predicate: NSPredicate, context: NSManagedObjectContext) {
3    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
4    fetchRequest.predicate = predicate
5
6    let batchDelete = NSBatchDeleteRequest(fetchRequest: fetchRequest)
7    try? context.execute(batchDelete)
8    try? context.save()
9}
10
11// Delete inactive users
12deleteWhere("User",
13    predicate: NSPredicate(format: "isActive == NO"),
14    context: viewContext
15)
16
17// Delete orders older than 30 days
18let thirtyDaysAgo = Calendar.current.date(byAdding: .day, value: -30, to: Date())!
19deleteWhere("Order",
20    predicate: NSPredicate(format: "createdAt < %@", thirtyDaysAgo as NSDate),
21    context: viewContext
22)

Common Pitfalls

  • Batch delete skips validation and cascade rules: NSBatchDeleteRequest operates on the SQLite store directly. It does not trigger cascade delete rules, validation, or willSave/didSave notifications. Use fetch-and-delete when relationships with cascade rules must be honored.
  • Stale objects in memory after batch delete: Objects loaded into the context before a batch delete become stale. Always merge changes with NSManagedObjectContext.mergeChanges(fromRemoteContextSave:into:) or call context.reset().
  • Forgetting WAL files: Deleting only the .sqlite file leaves -wal and -shm files, which can recreate the database with old data on next launch. Delete all three files.
  • Deleting on the wrong context: Perform deletes on a background context to avoid blocking the UI. Use container.newBackgroundContext() for heavy deletion operations.
  • Not saving after fetch-and-delete: context.delete(object) marks the object for deletion but does not persist the change. Call context.save() after all deletions to write changes to the store.

Summary

  • NSBatchDeleteRequest — fastest, operates on the store directly, requires manual context sync
  • Fetch-and-delete — slower but respects cascade rules and triggers notifications
  • destroyPersistentStore — nuclear option for full database reset
  • Delete with predicates for conditional clearing of specific records
  • Always merge batch delete changes into the context or call context.reset()
  • Delete all SQLite-related files (.sqlite, -wal, -shm) for a clean file-level reset

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions