Clearing CoreData and all that inside

Totumus Maximus picture Totumus Maximus · Feb 6, 2013 · Viewed 11.7k times · Source

I'm pretty new to CoreData and this app that uses it. And I'm currently working on a feature that clears the entire core data when I log out in the app.

I have 2 sqllite files (for some reason they thought that was handy)

How can I clear both files of all data and reset them into a dataless state?

I've tried a lot of ways, following guides, on SO.

How to clear/reset all CoreData in one-to-many relationship

how to remove all objects from Core Data

They all seem to fail for me. Now I'm wondering what do I do wrong? And perhaps someone can explain me how to reset my 2 CoreData files the proper way.

EDIT:

//should clear the whole coredata database. mainly used for logout mechanism
-(void)resetCoreData
{
    for (NSPersistentStore *store in self.persistentStoreCoordinator.persistentStores)
    {
//    NSPersistentStore *store = self.persistentStoreCoordinator.persistentStores[0];
        NSError *error;
        NSURL *storeURL = store.URL;
        DLog(@"storeURL: %@", storeURL);
        NSPersistentStoreCoordinator *storeCoordinator = self.persistentStoreCoordinator;
        [storeCoordinator removePersistentStore:store error:&error];
        [[NSFileManager defaultManager] removeItemAtPath:storeURL.path error:&error];

        DLog(@"There are erreurs: %@", error);
//    [self addDefaultData];
    }

    _persistentStoreCoordinator = nil;
    _managedObjectContext = nil;
    _managedObjectModel = nil;
}

This doesn't seem to clear the CoreData for me.

EDIT2:

- (NSManagedObjectContext *)managedObjectContext
{
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }
    
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        _managedObjectContext = [[NSManagedObjectContext alloc] init];
        [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    }
    return _managedObjectContext;
}

- (NSManagedObjectModel *)managedObjectModel
{
    if (__managedObjectModel != nil) {
        return __managedObjectModel;
    }

    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyName" withExtension:@"momd"];
    __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

    return __managedObjectModel;
}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

    if (__persistentStoreCoordinator != nil) {
        return __persistentStoreCoordinator;
    }

    NSString *storePath = [[self applicationDocumentsDirectory]

                           stringByAppendingPathComponent:@"MyName.sqlite"];

    NSFileManager *fileManager = [NSFileManager defaultManager];

    // If the expected store doesn't exist, copy the default store.
    if (![fileManager fileExistsAtPath:storePath]) {
        NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"MyName" ofType:@"momd"];
        if (defaultStorePath) {

            [fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];

        }

    }



    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];

    //Check to see what version of the current model we're in. If it's >= 2.0,
    //then and ONLY then check if migration has been performed...
    NSSet *versionIdentifiers = [[self managedObjectModel] versionIdentifiers];
    DLog(@"Which Current Version is our .xcdatamodeld file set to? %@", versionIdentifiers);

    if ([versionIdentifiers containsObject:@"2.0"])
    {
        BOOL hasMigrated = YES;
        if (hasMigrated==YES) {
            storePath = nil;
            storePath = [[self applicationDocumentsDirectory]
                         stringByAppendingPathComponent:@"MyName2.sqlite"];

        }
    }

    NSURL *storeUrl = [NSURL fileURLWithPath:storePath];
    NSError *error;
    NSDictionary *pscOptions = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                                [NSNumber numberWithBool:NO], NSInferMappingModelAutomaticallyOption,
                                nil];

    if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                                    configuration:nil
                                                              URL:storeUrl
                                                          options:pscOptions
                                                            error:&error]) {
        DLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    return __persistentStoreCoordinator;
}

Edit 3: I'm still looking for a way to reset my CoreData as if I deleted the entire app and started it up again. The usual ways of doing so are not working for my case. And there are 2 sqllite files. There are hints of a migration that took place at some point in the application but I'm not too sure when and how. Error logs show nothing useful.

I'm not looking for the most efficient way. Just the way.

Help me out and the bounty is yours.

Edit 4: FINAL RESULT: It seemed my legacy code had a second ManagedObjectContext instantiated. The moment I retrieved it and did the flush-function with it. Both sqlite-files disappeared as was needed.

Thanks to all that put effort in my problem.

Answer

yunas picture yunas · Feb 15, 2013

try the following method to flush the database, it works perfect for me.

-(void) flushDatabase{
    [__managedObjectContext lock];
    NSArray *stores = [__persistentStoreCoordinator persistentStores];
    for(NSPersistentStore *store in stores) {
       [__persistentStoreCoordinator removePersistentStore:store error:nil];
       [[NSFileManager defaultManager] removeItemAtPath:store.URL.path error:nil];
    }
    [__managedObjectContext unlock];
    __managedObjectModel    = nil;
    __managedObjectContext  = nil;
    __persistentStoreCoordinator = nil;
}