Delete/Reset all entries in Core Data?

后端 未结 30 2758
天命终不由人
天命终不由人 2020-11-22 16:00

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

相关标签:
30条回答
  • 2020-11-22 16:20

    The accepted answer is correct with removing URL by NSFileManager is correct, but as stated in iOS 5+ edit, the persistent store is not represented only by one file. For SQLite store it's *.sqlite, *.sqlite-shm and *.sqlite-wal ... fortunately since iOS 7+ we can use method

    [NSPersistentStoreCoordinator +removeUbiquitousContentAndPersistentStoreAtURL:options:error:]

    to take care of removal, so the code should be something like this:

    NSPersistentStore *store = ...;
    NSError *error;
    NSURL *storeURL = store.URL;
    NSString *storeName = ...;
    NSPersistentStoreCoordinator *storeCoordinator = ...;
    [storeCoordinator removePersistentStore:store error:&error];
    [NSPersistentStoreCoordinator removeUbiquitousContentAndPersistentStoreAtURL:storeURL.path options:@{NSPersistentStoreUbiquitousContentNameKey: storeName} error:&error];
    
    0 讨论(0)
  • 2020-11-22 16:20

    One other method (apart from a delete batch request) I often use (based on app requirement) is to reset the persistent store. The implementation looks like this for iOS 10+ and Swift (assuming you have a CoreDataManager class):

    let persistentContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name: "<Data-Model-Name>“)
        container.loadPersistentStores(completionHandler: { (storeDescription, err) in
            if let err = err {
                fatalError("loading of store failed: \(err)")
            }
        })
        return container
    }()
    
    func resetPersistentStore() {
    
        if let persistentStore = persistentContainer.persistentStoreCoordinator.persistentStores.last {
            let storeURL = persistentContainer.persistentStoreCoordinator.url(for: persistentStore)
    
            do {
                try persistentContainer.persistentStoreCoordinator.destroyPersistentStore(at: storeURL, ofType: NSSQLiteStoreType, options: nil)
            } catch {
                print("failed to destroy persistent store:", error.localizedDescription)
            }
    
            do {
                try persistentContainer.persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: nil)
            } catch {
                print("failed to re-add persistent store:", error.localizedDescription)
            }
        }
    
    }
    

    One advantage of this method is that it’s more straightforward especially when you have loads of data record for numerous entities in your core data. In which case a delete batch request would be memory intensive.

    0 讨论(0)
  • 2020-11-22 16:22

    Updated Solution for iOS 10+

    Use NSBatchDeleteRequest to delete all objects in the entity without having to load them into memory or iterate through them.

    // create the delete request for the specified entity
    let fetchRequest: NSFetchRequest<NSFetchRequestResult> = MyEntity.fetchRequest()
    let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
    
    // get reference to the persistent container
    let persistentContainer = (UIApplication.shared.delegate as! AppDelegate).persistentContainer
    
    // perform the delete
    do {
        try persistentContainer.viewContext.execute(deleteRequest)
    } catch let error as NSError {
        print(error)
    }
    

    This code has been updated for iOS 10 and Swift 3. If you need to support iOS 9, see this question.

    Sources:

    • Core Data: Quickest way to delete all instances of an entity (includes Objective-C code)
    • What's New in Core Data (WWDC 2015 video)
    • What's New in Core Data (WWDC 2016 video)
    • How to Use Core Data in iOS 10
    • What’s new in Core Data Swift 3.0
    0 讨论(0)
  • 2020-11-22 16:23

    I remove all data from core data on a button Event in a HomeViewController class: This article helped me so much I figured I'd contribute.

    -(IBAction)buttonReset:(id)sender
    {
        NSLog(@"buttonReset Pressed");
    
        //Erase the persistent store from coordinator and also file manager.
        NSPersistentStore *store = [self.persistentStoreCoordinator.persistentStores lastObject];
        NSError *error = nil;
        NSURL *storeURL = store.URL;
        [self.persistentStoreCoordinator removePersistentStore:store error:&error];
        [[NSFileManager defaultManager] removeItemAtURL:storeURL error:&error];
    
    
        NSLog(@"Data Reset");
    
        //Make new persistent store for future saves   (Taken From Above Answer)
        if (![self.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
            // do something with the error
        }
    
    }
    

    Note that in order to call self.persistentStoreCoordinator I declared a property in the Home View Controller. (Don't worry about the managedObjectContext that I use for saving and loading.)

    @property (nonatomic, retain) NSManagedObjectContext        *   managedObjectContext;
    @property (nonatomic, retain) NSPersistentStoreCoordinator  *   persistentStoreCoordinator;
    

    Then in the AppDelegate ApplicationDidFinishLaunching right below creating a HomeViewController I have :

    homeViewController = [[HomeViewController alloc] initWithNibName:@"HomeViewController" bundle:nil];
    homeViewController.managedObjectContext = self.managedObjectContext;
    homeViewController.persistentStoreCoordinator = self.persistentStoreCoordinator;
    
    0 讨论(0)
  • 2020-11-22 16:24

    Here is combined solution for purging Core Data.

    - (void)deleteAllObjectsInCoreData
    {
        NSArray *allEntities = self.managedObjectModel.entities;
        for (NSEntityDescription *entityDescription in allEntities)
        {
            NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
            [fetchRequest setEntity:entityDescription];
    
            fetchRequest.includesPropertyValues = NO;
            fetchRequest.includesSubentities = NO;
    
            NSError *error;
            NSArray *items = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    
            if (error) {
                    NSLog(@"Error requesting items from Core Data: %@", [error localizedDescription]);
                }
    
            for (NSManagedObject *managedObject in items) {
                [self.managedObjectContext deleteObject:managedObject];
            }
    
            if (![self.managedObjectContext save:&error]) {
                NSLog(@"Error deleting %@ - error:%@", entityDescription, [error localizedDescription]);
            }
        }  
    }
    
    0 讨论(0)
  • 2020-11-22 16:26

    I took Grouchal's code and to speed it up I used enumeration with concurrent mode (NSEnumerationConcurrent), it got a bit faster compared to for loop (in my app I added this feature for Testers so that they can clear data and do testcases rather than delete and install app)

    - (void)resetObjects
    {
        [self deleteAllObjectsInEntity:@"Entity1"];
        [self deleteAllObjectsInEntity:@"Entity2"];
        [self deleteAllObjectsInEntity:@"Entity3"];
        [self deleteAllObjectsInEntity:@"Entity4"];
    }
    
    -(void) deleteAllObjectsInEntity:(NSString*) entityName
    {
        MainDataContext *coreDataContext = [MainDataContext sharedInstance];
        NSManagedObjectContext *currentContext = coreDataContext.managedObjectContext;
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:currentContext];
        [fetchRequest setEntity:entity];
    
        NSError *error;
        NSArray *items = [currentContext executeFetchRequest:fetchRequest error:&error];
    
        [items enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSManagedObject * obj, NSUInteger idx, BOOL *stop) {
            [currentContext deleteObject:obj];
        }];
    
    
        if (![currentContext save:&error]) {
            NSLog(@"Error deleting %@ - error:%@",entityName,error);
        }
    }
    
    0 讨论(0)
提交回复
热议问题