Burjua
Burjua

Reputation: 12736

how to remove all objects from Core Data

how can I remove all objects? I know I can remove one by

[managedObjectContext deleteObject:objToDelete];

is it possible to delete all without iterating all array? thanks

Upvotes: 6

Views: 12324

Answers (7)

Nikolay Spassov
Nikolay Spassov

Reputation: 1316

I used stifin's code and updated it to use -performBlockAndWait:

- (BOOL)reset
{
    __block BOOL result = YES;

    [[self mainContext] performBlockAndWait:^{
        [[self mainContext] reset];

        NSArray* stores = [[self persistentStoreCoordinator] persistentStores];

        _mainContext = nil;
        _persistedContext = nil;

        for(NSPersistentStore* store in stores) {
            NSError* error;

            if(![[self persistentStoreCoordinator] removePersistentStore:store error:&error]) {
                debuglog(@"Error removing persistent store: %@", [error localizedDescription]);
                result = NO;
            }
            else {
                if(![[NSFileManager defaultManager] removeItemAtPath:store.URL.path error:&error]) {
                    debuglog(@"Error removing file of persistent store: %@", [error localizedDescription]);
                    result = NO;
                }
            }
        }

        _persistentStoreCoordinator = nil;
    }];

    return result;
}

Upvotes: 0

Luke Mcneice
Luke Mcneice

Reputation: 2720

This function removes the current SQLite db file from disk and creates a new one. It's much faster than any iterative delete.

-(void)deleteAndRecreateStore{
        NSPersistentStore * store = [[self.persistentStoreCoordinator persistentStores] lastObject];  
        NSError * error;    
        [self.persistentStoreCoordinator removePersistentStore:store error:&error];
        [[NSFileManager defaultManager] removeItemAtURL:[store URL] error:&error];
        __managedObjectContext = nil;
        __persistentStoreCoordinator = nil;
        [self managedObjectContext];//Rebuild The CoreData Stack  
}

If you want to call this outside Application Delegate (assuming boilerplate CoreData integration) you can use this to get a reference to your app delegate:

YourAppDelegate *appDelegate = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];

Don't forget to import the header.

Upvotes: 12

jorgegalindocruces
jorgegalindocruces

Reputation: 19

When you remove all the cache and documents, you are deleting the database. Not is necesary call to managedObjectContext

NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSArray *caches = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSMutableArray *paths = [NSMutableArray array];
[paths addObjectsFromArray:documents];
[paths addObjectsFromArray:caches];
for (NSUInteger i = 0; i < [paths count]; i++) {
    NSString *folderPath = [paths objectAtIndex:i];
    NSLog(@"Attempting to remove contents for: %@", folderPath);
    //Remove all cached data in the local app directory
    NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:folderPath error:&error];
    for (NSString *strName in dirContents) {
        [[NSFileManager defaultManager] removeItemAtPath:[folderPath stringByAppendingPathComponent:strName] error:&error];
        if (error != nil) {
            NSLog(@"Error removing item: %@ : %@", strName, error.description);
        } else {
            NSLog(@"Removed item: %@", strName);
        }
    }
}

Upvotes: 1

stifin
stifin

Reputation: 1400

this is what I do to "reset" my data store:

- (BOOL)resetDatastore
{
    [[self managedObjectContext] lock];
    [[self managedObjectContext] reset];
    NSPersistentStore *store = [[[self persistentStoreCoordinator] persistentStores] lastObject]; 
    BOOL resetOk = NO;

    if (store)
    {
        NSURL *storeUrl = store.URL;
        NSError *error;

        if ([[self persistentStoreCoordinator] removePersistentStore:store error:&error])
        {
            [[self persistentStoreCoordinator] release];
            __persistentStoreCoordinator = nil;
            [[self managedObjectContext] release];
            __managedObjectContext = nil;

            if (![[NSFileManager defaultManager] removeItemAtPath:storeUrl.path error:&error])
            {
                NSLog(@"\nresetDatastore. Error removing file of persistent store: %@",
                  [error localizedDescription]);
                resetOk = NO;
            }
            else
            {
                //now recreate persistent store
                [self persistentStoreCoordinator];
                [[self managedObjectContext] unlock];
                resetOk = YES;
            }
        }
        else
        {
            NSLog(@"\nresetDatastore. Error removing persistent store: %@",
              [error localizedDescription]);
            resetOk = NO;
        }
        return resetOk;
    }
    else
    {
        NSLog(@"\nresetDatastore. Could not find the persistent store");
        return resetOk;
    }
}

Upvotes: 8

Chris Hanson
Chris Hanson

Reputation: 55174

Marking objects for deletion and then saving works the way it does because Core Data still needs to run the validation rules for all of the objects being deleted. After all, an object can refuse deletion based on how it responds to -validateForDelete:.

If:

  • you truly want to delete everything in a persistent store
  • and you don't care about whether the objects in that persistent store say they're valid for deletion

Then:

  • tear down the Core Data stack that's using that persistent store
  • and delete the persistent store's file.

Upvotes: 8

Marcus S. Zarra
Marcus S. Zarra

Reputation: 46728

You can also just tear down the stack (releasing the NSManagedObjectContext, NSPersistentStore and NSManagedObjectModel) and delete the file. Probably would be faster than iterating over your entire database and deleting each object individually.

Also, it is unlikely they will provide this functionality in the future because it is easy to delete the file. However if you feel it is important then file a radar and let Apple know. Otherwise they won't know how many people want this feature.

Upvotes: 6

Jesse Naugher
Jesse Naugher

Reputation: 9820

Just iterate the array and delete them. There isn't a defined method for deleting them all.

Upvotes: 1

Related Questions