iOS: Delete ALL Core Data Swift

IosSwiftCore Data

Ios Problem Overview


I am a little confused as to how to delete all core data in swift. I have created a button with an IBAction linked. On the click of the button I have the following:

let appDel: foodforteethAppDelegate = UIApplication.sharedApplication().delegate as foodforteethAppDelegate
    let context: NSManagedObjectContext = appDel.managedObjectContext

Then I've messed around with various methods to try and delete all the core data content but I can't seem to get it to work. I've used removeAll to delete from a stored array but still can't delete from the core data. I assume I need some type of for loop but unsure how to go about making it from the request.

I have tried applying the basic principle of deleting a single row

func tableView(tableView: UITableView!, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath!) {
    
    let appDel: foodforteethAppDelegate = UIApplication.sharedApplication().delegate as foodforteethAppDelegate
    let context:NSManagedObjectContext = appDel.managedObjectContext
    
    if editingStyle == UITableViewCellEditingStyle.Delete {
        
        if let tv = tblTasks {
            context.deleteObject(myList[indexPath!.row] as NSManagedObject)
            myList.removeAtIndex(indexPath!.row)
            tv.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Fade)
        }
        
        var error: NSError? = nil
        if !context.save(&error) {
            abort()
        }
        
    }
    
}

However, the issue with this is that when I click a button, I don't have the indexPath value and also I need to loop through all the values which I can't seem to do with context.

Ios Solutions


Solution 1 - Ios

Try this simple solution:

func deleteAllData(entity: String)
{
    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    let managedContext = appDelegate.managedObjectContext
    let fetchRequest = NSFetchRequest(entityName: entity)
    fetchRequest.returnsObjectsAsFaults = false
        
    do 
    {
        let results = try managedContext.executeFetchRequest(fetchRequest)
        for managedObject in results
        {
            let managedObjectData:NSManagedObject = managedObject as! NSManagedObject
            managedContext.deleteObject(managedObjectData)
        }
    } catch let error as NSError {
        print("Detele all data in \(entity) error : \(error) \(error.userInfo)")
    }
}

Swift 4

func deleteAllData(_ entity:String) {
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
    fetchRequest.returnsObjectsAsFaults = false
    do {
        let results = try dataController.viewContext.fetch(fetchRequest)
        for object in results {
            guard let objectData = object as? NSManagedObject else {continue}
            dataController.viewContext.delete(objectData)
        }
    } catch let error {
        print("Detele all data in \(entity) error :", error)
    }
}

Implementation:

 self.deleteAllData("your_entityName")

Solution 2 - Ios

You can use destroyPersistentStore starting in iOS 9.0 and Swift 3:

public func clearDatabase() {
    guard let url = persistentContainer.persistentStoreDescriptions.first?.url else { return }
    
    let persistentStoreCoordinator = persistentContainer.persistentStoreCoordinator

     do {
         try persistentStoreCoordinator.destroyPersistentStore(at:url, ofType: NSSQLiteStoreType, options: nil)
         try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: nil)
     } catch {
         print("Attempted to clear persistent store: " + error.localizedDescription)
     }
}

Solution 3 - Ios

To Delete all data you can use NSBatchDeleteRequest

func deleteAllData(entity: String)
{
    let ReqVar = NSFetchRequest(entityName: entity)
    let DelAllReqVar = NSBatchDeleteRequest(fetchRequest: ReqVar)
    do { try ContxtVar.executeRequest(DelAllReqVar) }
    catch { print(error) }
}

Solution 4 - Ios

I have got it working using the following method:

@IBAction func btnDelTask_Click(sender: UIButton){
    
    let appDel: foodforteethAppDelegate = UIApplication.sharedApplication().delegate as foodforteethAppDelegate
    let context: NSManagedObjectContext = appDel.managedObjectContext  
    let request = NSFetchRequest(entityName: "Food")

    myList = context.executeFetchRequest(request, error: nil)
    
    
    if let tv = tblTasks {
        
        var bas: NSManagedObject!
      
        for bas: AnyObject in myList
        {
           context.deleteObject(bas as NSManagedObject)
        }
        
        myList.removeAll(keepCapacity: false)
     
        tv.reloadData()
        context.save(nil)
    }
}

However, I am unsure whether this is the best way to go about doing it. I'm also receiving a 'constant 'bas' inferred to have anyobject' error - so if there are any solutions for that then it would be great

EDIT

Fixed by changing to bas: AnyObject

Solution 5 - Ios

For Swift 3.0

func DeleteAllData(){
    
    
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let managedContext = appDelegate.persistentContainer.viewContext
    let DelAllReqVar = NSBatchDeleteRequest(fetchRequest: NSFetchRequest<NSFetchRequestResult>(entityName: "Entity"))
    do {
        try managedContext.execute(DelAllReqVar)
    }
    catch {
        print(error)
    }
}

Solution 6 - Ios

Here is my implementation to clear all core data in Swift 3, based on Jayant Dash's excellent (and comprehensive) answer. This is simpler due to only supporting iOS10+. It deletes all core data entities, without having to hardcode them.

public func clearAllCoreData() {
    let entities = self.persistentContainer.managedObjectModel.entities
    entities.flatMap({ $0.name }).forEach(clearDeepObjectEntity)
}

private func clearDeepObjectEntity(_ entity: String) {
    let context = self.persistentContainer.viewContext
    
    let deleteFetch = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
    let deleteRequest = NSBatchDeleteRequest(fetchRequest: deleteFetch)
    
    do {
        try context.execute(deleteRequest)
        try context.save()
    } catch {
        print ("There was an error")
    }
}

Solution 7 - Ios

Swift 5.1

Most of the posts here suggests to create a function to delete all entities by name and then delete all your entities by name. like so :

resetEntity(named: "MyEntity1")
resetEntity(named: "MyEntity2")
resetEntity(named: "MyEntity3")
...

But if the real question is how to clean ALL CoreData entity in one go, I suggest you loop over entity names:

// Supposing this is a CoreDataController/CoreDataStack class where you have access to `viewContext` and `persistantContainer`
// Otherwise just pass the `persistantContainer` as a parameter, from which you can also retrieve the `viewContext` 
func resetAllCoreData() {

     // get all entities and loop over them
     let entityNames = self.persistentContainer.managedObjectModel.entities.map({ $0.name!})
     entityNames.forEach { [weak self] entityName in   
        let deleteFetch = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
        let deleteRequest = NSBatchDeleteRequest(fetchRequest: deleteFetch)

        do {
            try self?.context.execute(deleteRequest)
            try self?.context.save()
        } catch {
            // error
        }
    }
}

Hope this can help

Solution 8 - Ios

In Swift 3.0

 func deleteAllRecords() {
        //delete all data
        let context = appDelegate.persistentContainer.viewContext
        
        let deleteFetch = NSFetchRequest<NSFetchRequestResult>(entityName: "YourClassName")
        let deleteRequest = NSBatchDeleteRequest(fetchRequest: deleteFetch)
        
        do {
            try context.execute(deleteRequest)
            try context.save()
        } catch {
            print ("There was an error")
        }
    }

Solution 9 - Ios

For Swift 4.0 (modified version of svmrajesh's answerā€¦ or at least what Xcode turned it into before it would run it for me.)

func deleteAllData(entity: String) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
fetchRequest.returnsObjectsAsFaults = false

do
{
    let results = try managedContext.fetch(fetchRequest)
    for managedObject in results
    {
        let managedObjectData:NSManagedObject = managedObject as! NSManagedObject
        managedContext.delete(managedObjectData)
    }
} catch let error as NSError {
    print("Delete all data in \(entity) error : \(error) \(error.userInfo)")
}
}

Implementation:

deleteAllData(entity: "entityName")

Solution 10 - Ios

In Swift UI

when you select core data at the beginning of project the persistence coordinator is automatically created by swift in app delegate. The scene delegate creates @environmentObject for managed context

let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

let contentView = ContentView().environment(\.managedObjectContext, context)

create instance of manageObjectContext in content view and also fetchRequest object using property wrapper @FetchRequest

@Environment(\.managedObjectContext) var moc
@FetchRequest(entity: EntityName.entity(), sortDescriptors: []) var entityNames: FetchedResults<EntityName>

For delete action perform

for entityName in entityNames {
moc.delete(entityName)
}
try? moc.save()

try operation can throw error so please implement do try catch block in production code to handle error properly.

Solution 11 - Ios

This clean() method will fetch entities list from DataModel and clear all data.

func deleteAll(entityName: String) -> Error? {
            if #available(iOS 9.0, *) {
                do {
                    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
                    let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
                    try context.execute(batchDeleteRequest)
                } catch {
                    return error
                }
                return nil
            } else {
                let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
                fetchRequest.returnsObjectsAsFaults = false
                do
                {
                    let results = try context.fetch(fetchRequest)
                    for managedObject in results
                    {
                        if let managedObjectData:NSManagedObject = managedObject as? NSManagedObject {
                            context.delete(managedObjectData)
                        }
                    }
                } catch  {
                    return error
                }
                return nil
            }
        }
        
        var objectModel: NSManagedObjectModel? {
            if #available(iOS 10.0, *) {
                return persistentContainer.managedObjectModel
            } else {
                return persistentStoreCoordinator?.managedObjectModel
            }
        }
        
        open func clean() {
            if let models = objectModel?.entities {
                for entity in models {
                    if let entityName = entity.name {
                        _ = deleteAll(entityName: entityName)
                    }
                }
            }
        }

Happy Coding!

Solution 12 - Ios

Swift 5.1

let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
        
        do {
            try coreDataManager.managedObjectContext.execute(batchDeleteRequest)
        } catch {
            print("Detele all data in \(entityName) error :", error)
        }

Solution 13 - Ios

There are two simple methods as far as i know , first

Method 1:

Fetch, Delete, Repeat

// Initialize Fetch Request

let fetchRequest = NSFetchRequest(entityName: "Item")

// Configure Fetch Request

 fetchRequest.includesPropertyValues = false

do {

let items = try managedObjectContext.executeFetchRequest(fetchRequest) as! [NSManagedObject]

for item in items {
    managedObjectContext.deleteObject(item)
}

// Save Changes
try managedObjectContext.save()

} catch {
// Error Handling
// ...

}

Methode 2:

Batch Delete Request

// Create Fetch Request

let fetchRequest = NSFetchRequest(entityName: "Item")

// Create Batch Delete Request

     let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
       do {
          try managedObjectContext.executeRequest(batchDeleteRequest)

          } catch {
// Error Handling
    }

I have tested both and they both work fine

Solution 14 - Ios

Swift 5

func deleteAllData(entity: String){

guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
fetchRequest.returnsObjectsAsFaults = false

do {
    let arrUsrObj = try managedContext.fetch(fetchRequest)
    for usrObj in arrUsrObj as! [NSManagedObject] {            
        managedContext.delete(usrObj)
    }
   try managedContext.save() //don't forget
    } catch let error as NSError {
    print("delete fail--",error)
  }

}

Solution 15 - Ios

To delete all entries in Core Data I have found 2 ways of doing it

1 - With a for func

func deleteEntries() {
    do {
        let managedObjectContext = try CoreDataStack.sharedInstance.getContext()
        for record in records {
            managedObjectContext.delete(record)
        }
        try managedObjectContext.save()
    } catch let error {
        print(error.localizedDescription)
    }
}

2 - With a NSBatchDeleteRequest

func deleteEntries() {
    do {
        let managedObjectContext = try CoreDataStack.sharedInstance.getContext()
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Location")
        let request: NSBatchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
        try managedObjectContext.execute(request)
        try managedObjectContext.save()
    } catch let error {
        print(error.localizedDescription)
    }
}

I recommend using number 2 because is a better way of handling resources in your app

Solution 16 - Ios

An alternative can be to completely remove and recreate persistent store (iOS 10+, swift 3).

let urls = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask);
    var dbUrl = urls[urls.count-1];
    dbUrl = dbUrl.appendingPathComponent("Application Support/nameOfYourCoredataFile.sqlite")
    do {
        try persistentContainer.persistentStoreCoordinator.destroyPersistentStore(at: dbUrl, ofType: NSSQLiteStoreType, options: nil);
    } catch {
        print(error);
    }
    do {
        try persistentContainer.persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: dbUrl, options: nil);
    } catch {
        print(error);
    }

Solution 17 - Ios

Similar to above but with AppDelegte call taken out and UIView variable used

var context: NSManagedObjectContext?
//deleting Message

func deleteMessages(entity: String) {
   do {
      let request = NSFetchRequest(entityName: entity)
      print(request)

      if let result = try context!.executeFetchRequest(request) as? [your class of NSManagedObject] {
          for message in result {
             context!.deleteObject(message)
             try context!.save()
             print(message)
             self.tableView.reloadData()
          }
      }
   } catch {
         print("miss")
   }
}

To use call function

self.deleteMessages("TimeMaster")

Solution 18 - Ios

I use this one for delete all the core data entities in Swift3

func deleteAllCD(){
    for entityName in ["EntityName", "AnotherEntityName"]{
        let request = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
        let delAllReqVar = NSBatchDeleteRequest(fetchRequest: request)
        do { try persistentContainer.viewContext.execute(delAllReqVar) }
        catch { print(error) }
    }
}

Solution 19 - Ios

Swift 3

// Replace 'MyEntityName' with your managed object class.
let moc = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let fetchRequest: NSFetchRequest<MyEntityName> = MyEntityName.fetchRequest()
fetchRequest.returnsObjectsAsFaults = false
moc.perform {
    do {
        let myEntities = try fetchRequest.execute()
        for myEntity in myEntities {
            moc.delete(myEntity)
        }
        try moc.save()
    } catch let error {
        print("Delete Error: \(error.localizedDescription)")
    }
}

Solution 20 - Ios

Try this:

func deleteAllData(entity: String)
{
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let context = appDelegate.persistentContainer.viewContext
    let ReqVar = NSFetchRequest(entityName: entity)
    let DelAllReqVar = NSBatchDeleteRequest(fetchRequest: ReqVar)
    do { try ContxtVar.executeRequest(DelAllReqVar) }
    catch { print(error) }
}

Solution 21 - Ios

Swift 4 :

destroyPersistentStoreAtURL(_:withType:options:) will delete (or truncate) the target persistent store. This will safely destroy a persistent store.

Add:

do {
    try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: persistentStoreURL, options: nil)
} catch {
    // Error Handling
}

Destroy / Delete / Truncate:

do {
    try persistentStoreCoordinator.destroyPersistentStoreAtURL(persistentStoreURL, withType: NSSQLiteStoreType, options: nil)
} catch {
    // Error Handling
}

Note : Parameters in above method should be identical to addPersistentStoreWithType method. You need to re-initiate storeCoordinator to use store again.

Solution 22 - Ios

For Swift 4.0

  func deleteAllData(_ entity:String) {

    let managedContext =  DatabaseController.getContext().persistentStoreCoordinator
     let context = DatabaseController.getContext()
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
    let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
    do {
        try managedContext?.execute(batchDeleteRequest, with: context)
    }
    catch {
        print(error)
    }
  
 
  }

Solution 23 - Ios

Swift 4

From iOS 9, there is the possibility of erasing persistent storage. For better maintenance ā€“ create NSPersistentStoreCoordinator extension with abstract function.

extension NSPersistentStoreCoordinator {
    func destroyPersistentStore(type: String) -> NSPersistentStore? {
        guard 
            let store = persistentStores.first(where: { $0.type == type }),
            let storeURL = store.url 
        else {
            return nil
        }
        
        try? destroyPersistentStore(at: storeURL, ofType: store.type, options: nil)

        return store
    }
}

Then destroying SQLite persistent storage looks pretty simple:

let coordinator = persistentContainer.persistentStoreCoordinator
let store = coordinator.destroyPersistentStore(type: NSSQLiteStoreType)

Recommendations
  1. Update destroyPersistentStore function which is no-nullable and throws specific errors, for example CoreDataError enum.
  2. Probably you want to refresh your persistent storage. For this, you can use addPersistentStore function of NSPersistentStoreCoordinator, with retrieved NSPersistentStore object from destroyPersistentStore.

Solution 24 - Ios

static func fetch<T>(entity: T.Type, withPredicate predicate: NSPredicate? = nil) -> Array<T>? where T : NSManagedObject {
    let request: NSFetchRequest<T> = NSFetchRequest<T>(entityName: String(describing: T.self))
    request.predicate = predicate
    do {
        return try context.fetch(request)
    }catch{
        print(error.localizedDescription)
    }
    return nil
}

 static func delete<T>(_ object: T) where T : NSManagedObject {
    context.delete(object)
    saveContext()
}

static func reset<T>(entity: T.Type) where T : NSManagedObject {
    fetch(entity: entity.self)?.forEach{
        delete($0)
    }
    
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPrateekView Question on Stackoverflow
Solution 1 - IosRajesh LoganathanView Answer on Stackoverflow
Solution 2 - IosgogoslabView Answer on Stackoverflow
Solution 3 - IosSujay U NView Answer on Stackoverflow
Solution 4 - IosPrateekView Answer on Stackoverflow
Solution 5 - Iosanshul kingView Answer on Stackoverflow
Solution 6 - IosrmooneyView Answer on Stackoverflow
Solution 7 - IosOlympiloutreView Answer on Stackoverflow
Solution 8 - IosAmul4608View Answer on Stackoverflow
Solution 9 - IosriherdView Answer on Stackoverflow
Solution 10 - IosAshim DahalView Answer on Stackoverflow
Solution 11 - IosJayant DashView Answer on Stackoverflow
Solution 12 - IosMohammad RazipourView Answer on Stackoverflow
Solution 13 - IosraddaouiView Answer on Stackoverflow
Solution 14 - IosEnamul HaqueView Answer on Stackoverflow
Solution 15 - IosIker SolozabalView Answer on Stackoverflow
Solution 16 - IosgrepView Answer on Stackoverflow
Solution 17 - Iosgje4View Answer on Stackoverflow
Solution 18 - IosAlexey LysenkoView Answer on Stackoverflow
Solution 19 - IosChris ChuteView Answer on Stackoverflow
Solution 20 - IosFarshid roohiView Answer on Stackoverflow
Solution 21 - IosNikunj JoshiView Answer on Stackoverflow
Solution 22 - IosPankaj JangidView Answer on Stackoverflow
Solution 23 - IosdimpiaxView Answer on Stackoverflow
Solution 24 - IosimpalairisView Answer on Stackoverflow