Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clearing CoreData and all that inside

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.

like image 515
Totumus Maximus Avatar asked Feb 06 '13 11:02

Totumus Maximus


People also ask

How do I delete all data from Core Data?

One approach to delete everything and reset Core Data is to destroy the persistent store. Deleting and re-creating the persistent store will delete all objects in Core Data.

Where is Core Data stored?

The persistent store should be located in the AppData > Library > Application Support directory.

How do I use Core Data?

Use Core Data to save your application's permanent data for offline use, to cache temporary data, and to add undo functionality to your app on a single device. To sync data across multiple devices in a single iCloud account, Core Data automatically mirrors your schema to a CloudKit container.


Video Answer


2 Answers

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;
}
like image 68
yunas Avatar answered Sep 22 '22 23:09

yunas


NSPersistentStoreCoordinator *storeCoordinator = self.persistentStoreCoordinator;
[storeCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtPath:storeURL.path error:&error];

So you're removing the persistent store from the persistent store coordinator, and then trying to delete the file. But just removing the store from the coordinator isn't enough to guarantee that the file associated with the store has been closed, and if it hasn't then the file system will probably prevent you from deleting the file. I can't tell from your question whether you're using ARC here, but since you say that it's old code there's a good chance that you aren't. Either way, if removing the store causes it to be autoreleased instead of released, or if you keep any other references to the store anywhere, then the store won't be deallocated just because you removed it from the coordinator, the file may remain open, and deleting the file will fail.

A good way to see what's really going on, in addition to looking at the error object provided by -removeItemAtPath:error:, is to take a look in the file system and see whether the file is still there after you try to remove it. Go to the Organizer window, select your device and application, and download a copy of the app's sandbox. You should then be able to see whether the file is really being deleted.

If you do see that the files are being deleted as you think they should be, then look for other ways that the data may be restored. If UserA logs out and then UserB logs into the app while it's still running, are you sure that you've started with a fresh managed object context? Is it possible that UserA's data remains in the MOC? It could then be written out when you create and add a new store. Another possibility that occurs to me is that iCloud is "helping" here. I see that your data files are kept in the Documents directory, and iOS will normally try to keep files in that directory backed up to iCloud. Perhaps when you create a new store for UserB's data, iCloud adds UserA's records back to that store. (Seems unlikely -- I'm pretty sure iCloud is more sophisticated than that -- but something to check.)

like image 35
Caleb Avatar answered Sep 20 '22 23:09

Caleb