Do you know of any way to delete all of the entries stored in Core Data? My schema should stay the same; I just want to reset it to blank.
Edit
Swift 4/5, iOS 9+
Rebuilding the whole CoreData
SQLite file will make sure all data is erased, therefore all entities are deleted. Just call deleteAndRebuild()
.
class CoreDataStack {
// Change this
static let datamodelName = "ProjectName"
static let storeType = "sqlite"
static let persistentContainer = NSPersistentContainer(name: datamodelName)
private static let url: URL = {
let url = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0].appendingPathComponent("\(datamodelName).\(storeType)")
assert(FileManager.default.fileExists(atPath: url.path))
return url
}()
static func loadStores() {
persistentContainer.loadPersistentStores(completionHandler: { (nsPersistentStoreDescription, error) in
if let error = error {
fatalError(error.localizedDescription)
}
})
}
static func deleteAndRebuild() {
try! persistentContainer.persistentStoreCoordinator.destroyPersistentStore(at: url, ofType: storeType, options: nil)
loadStores()
}
}
here my swift3 version for delete all records. 'Users' is entity name
@IBAction func btnDelAll_touchupinside(_ sender: Any) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedObjectContext = appDelegate.persistentContainer.viewContext
let fetchReq = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")
let req = NSBatchDeleteRequest(fetchRequest: fetchReq)
do {
try managedObjectContext.execute(req)
} catch {
// Error Handling
}
}
I've written a clearStores
method that goes through every store and delete it both from the coordinator and the filesystem (error handling left aside):
NSArray *stores = [persistentStoreCoordinator persistentStores];
for(NSPersistentStore *store in stores) {
[persistentStoreCoordinator removePersistentStore:store error:nil];
[[NSFileManager defaultManager] removeItemAtPath:store.URL.path error:nil];
}
[persistentStoreCoordinator release], persistentStoreCoordinator = nil;
This method is inside a coreDataHelper
class that takes care of (among other things) creating the persistentStore when it's nil.
Delete the persistent store file and setup a new persistent store coordinator?
Assuming you are using MagicalRecord
and have a default persistence store:
I don't like all the solutions that assume certain files to exist and/or demand entering the entities names or classes. This is a Swift(2), safe way to delete all the data from all the entities. After deleting it will recreate a fresh stack too (I am actually not sure as to how neccessery this part is).
It's godo for "logout" style situations when you want to delete everything but have a working store and moc to get new data in (once the user logs in...)
extension NSManagedObject {
class func dropAllData() {
MagicalRecord.saveWithBlock({ context in
for name in NSManagedObjectModel.MR_defaultManagedObjectModel().entitiesByName.keys {
do { try self.deleteAll(name, context: context) }
catch { print("⚠️ ✏️ Error when deleting \(name): \(error)") }
}
}) { done, err in
MagicalRecord.cleanUp()
MagicalRecord.setupCoreDataStackWithStoreNamed("myStoreName")
}
}
private class func deleteAll(name: String, context ctx: NSManagedObjectContext) throws {
let all = NSFetchRequest(entityName: name)
all.includesPropertyValues = false
let allObjs = try ctx.executeFetchRequest(all)
for obj in allObjs {
obj.MR_deleteEntityInContext(ctx)
}
}
}
[Late answer in response to a bounty asking for newer responses]
Looking over earlier answers,
But there's a different, similar approach to removing the persistent store that does work. The key is to put your persistent store file in its own sub-directory that doesn't contain anything else. Don't just stick it in the documents directory (or wherever), create a new sub-directory just for the persistent store. The contents of that directory will end up being the persistent store file, the journal files, and the external binary files. If you want to nuke the entire data store, delete that directory and they'll all disappear.
You'd do something like this when setting up your persistent store:
NSURL *storeDirectoryURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"persistent-store"];
if ([[NSFileManager defaultManager] createDirectoryAtURL:storeDirectoryURL
withIntermediateDirectories:NO
attributes:nil
error:nil]) {
NSURL *storeURL = [storeDirectoryURL URLByAppendingPathComponent:@"MyApp.sqlite"];
// continue with storeURL as usual...
}
Then when you wanted to remove the store,
[[NSFileManager defaultManager] removeItemAtURL:storeDirectoryURL error:nil];
That recursively removes both the custom sub-directory and all of the Core Data files in it.
This only works if you don't already have your persistent store in the same folder as other, important data. Like the documents directory, which probably has other useful stuff in it. If that's your situation, you could get the same effect by looking for files that you do want to keep and removing everything else. Something like:
NSString *docsDirectoryPath = [[self applicationDocumentsDirectory] path];
NSArray *docsDirectoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:docsDirectoryPath error:nil];
for (NSString *docsDirectoryItem in docsDirectoryContents) {
// Look at docsDirectoryItem. If it's something you want to keep, do nothing.
// If it's something you don't recognize, remove it.
}
This approach may be error prone. You've got to be absolutely sure that you know every file you want to keep, because otherwise you might remove important data. On the other hand, you can remove the external binary files without actually knowing the file/directory name used to store them.