objective c - Borrando CoreData y todo eso dentro
objective-c core-data (4)
Si su aplicación puede crear los archivos, simplemente elimínelos cuando la aplicación se cierre. Si tiene alguna noción de una base de datos que tiene información de esquema valiosa, y solo necesita truncar el archivo, ese no es realmente el caso en los datos centrales ... El esquema está en los modelos de entidad compilados y en los archivos xcwhatever.
También debo haber leído mal, porque si desea que los datos centrales no sean persistentes, entonces está utilizando la herramienta incorrecta.
Soy bastante nuevo en CoreData y esta aplicación que lo usa. Y actualmente estoy trabajando en una función que borra toda la información básica cuando cierro sesión en la aplicación.
Tengo 2 archivos sqlite (por alguna razón pensaron que era útil)
¿Cómo puedo borrar ambos archivos de todos los datos y restaurarlos a un estado sin datos?
Lo intenté de muchas maneras, siguiendo las guías, en SO.
Cómo borrar / restablecer todos los CoreData en una relación de uno a muchos
cómo eliminar todos los objetos de Core Data
Todos parecen fallar para mí. Ahora me pregunto, ¿qué hago mal? Y tal vez alguien me puede explicar cómo restablecer mis 2 archivos CoreData de la manera correcta.
EDITAR:
//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;
}
Esto no parece borrar el CoreData para mí.
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;
}
Editar 3: sigo buscando una forma de restablecer mi CoreData como si hubiera eliminado toda la aplicación y la haya reiniciado. Las formas habituales de hacerlo no funcionan para mi caso. Y hay 2 archivos sqlite. Hay indicios de una migración que tuvo lugar en algún momento de la aplicación, pero no estoy muy seguro de cuándo y cómo. Los registros de errores no muestran nada útil.
No estoy buscando la forma más eficiente. Justo así.
Ayúdame y la recompensa es tuya.
Edición 4: RESULTADO FINAL: Parecía que mi código heredado tenía un segundo ManagedObjectContext instanciado. En el momento en que lo recuperé e hice la función de descarga con él. Ambos archivos sqlite desaparecieron según era necesario.
Gracias a todos los que pusieron esfuerzo en mi problema.
Utilizo esta función en el AppDelegate de una de mis aplicaciones ...
- (void)deleteAllCoreData
{
NSPersistentStore *store = self.persistentStoreCoordinator.persistentStores[0];
NSError *error;
NSURL *storeURL = store.URL;
NSPersistentStoreCoordinator *storeCoordinator = self.persistentStoreCoordinator;
[storeCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtPath:storeURL.path error:&error];
__persistentStoreCoordinator = nil;
__managedObjectContext = nil;
__managedObjectModel = nil;
[self addDefaultData];
}
Elimina la tienda persistente que utiliza CoreData y la deja para que se configure una nueva cuando se accede nuevamente a los datos principales.
Este es el método descrito en el segundo enlace que proporcionó.
NSPersistentStoreCoordinator *storeCoordinator = self.persistentStoreCoordinator;
[storeCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtPath:storeURL.path error:&error];
Entonces quita la tienda persistente del coordinador de tienda persistente y luego intenta eliminar el archivo. Pero simplemente eliminar la tienda del coordinador no es suficiente para garantizar que el archivo asociado a la tienda se haya cerrado, y si no lo ha hecho, entonces el sistema de archivos probablemente evitará que elimine el archivo. No puedo decir a partir de su pregunta si está usando ARC aquí, pero como dice que es código antiguo, hay muchas posibilidades de que no lo sea. De cualquier manera, si eliminar la tienda hace que se libere automáticamente en lugar de soltarse, o si guarda otras referencias a la tienda en cualquier lugar, entonces la tienda no será desasignada solo porque la eliminó del coordinador, el archivo puede permanecer abierto , y eliminar el archivo fallará.
Una buena forma de ver qué está sucediendo realmente, además de observar el objeto de error proporcionado por -removeItemAtPath:error:
es echar un vistazo al sistema de archivos y ver si el archivo sigue ahí después de intentar eliminarlo. Vaya a la ventana de Organizador, seleccione su dispositivo y aplicación, y descargue una copia de la zona de pruebas de la aplicación. Debería poder ver si el archivo realmente está siendo eliminado.
Si ve que los archivos se están eliminando como cree que deberían ser, busque otras formas en que se puedan restaurar los datos. Si el usuario A cierra la sesión y luego el usuario B inicia sesión en la aplicación mientras aún se está ejecutando, ¿está seguro de haber comenzado con un nuevo contexto de objeto administrado? ¿Es posible que los datos de UserA permanezcan en el MOC? Luego podría escribirse cuando cree y agregue una nueva tienda. Otra posibilidad que se me ocurre es que iCloud está "ayudando" aquí. Veo que sus archivos de datos se mantienen en el directorio de Documentos, y iOS normalmente intentará mantener los archivos en ese directorio respaldados en iCloud. Quizás cuando crea una nueva tienda para los datos del Usuario B, iCloud agrega los registros de la A UserA a esa tienda. (Parece poco probable, estoy bastante seguro de que iCloud es más sofisticado que eso, pero algo para comprobar).
Prueba el siguiente método para limpiar la base de datos, funciona perfecto para mí.
-(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;
}