iphone core-data

Error 134130 del cacao de la migración ligera de los datos básicos del iPhone: No se puede encontrar el modelo para la tienda de origen



core-data (5)

Leí varias recetas que solicitan eliminar y volver a instalar la aplicación, que funciona tanto para el simulador como para el teléfono, pero me temo que cuando lo publique a usuarios reales, se romperá mi base instalada ya que no podrán eliminarse ni reinstalarse. .

Este es un problema causado por Xcode que no elimina los archivos antiguos de momc del simulador / dispositivo dev cuando se cambia el archivo modelo, por ejemplo, cambiando el nombre. Queda el archivo antiguo que causa confusión. Esto es algo que solo se ve durante el desarrollo porque es un artefacto de la forma en que Xcode manipula el paquete de aplicaciones sin reinstalarlo completamente cada vez que debe ocurrir con una versión de lanzamiento.

Puede confirmar este registro la devolución de:

[[NSBundle mainBundle] URLsForResourcesWithExtension:@"momc"subdirectory:nil];

... que debería mostrar todos los archivos de modelo compilados en el paquete de aplicaciones

Es una mala práctica confiar en la migración durante el desarrollo porque es muy común que la migración falle si está realizando cambios en el modelo y la tienda. Solo debe utilizar la migración después de que todo el código esté determinado. También recomendaría regenerar tu tienda desde cero cada vez que corres. Es muy fácil acumular basura en la tienda cambiando el modelo.

Gente

La migración ligera está fallando para mí el 100% del tiempo en esta línea:

[persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]

con el error:

Error: Error Domain=NSCocoaErrorDomain Code=134130 UserInfo=0x4fbff20 "Operation could not be completed. (Cocoa error 134130.)" "Can''t find model for source store";

Aquí está mi contexto de objeto gestionado, modelo y almacén persistente:

- (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; } managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain]; return managedObjectModel; } - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (persistentStoreCoordinator != nil) { return persistentStoreCoordinator; } NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"Locations.sqlite"]]; NSError *error; persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]]; // Allow inferred migration from the original version of the application. NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) { NSLog(@"Error: %@",error); NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } return persistentStoreCoordinator; }

Tengo dos versiones de mi modelo en mi proyecto: una versión 4 y una versión 5. Si configuro mi versión 4 como predeterminada, funciona bien. Si selecciono "Diseño -> Modelo de datos -> Agregar versión del modelo" (como se describe en esta publicación ), hago un cambio, Diseño -> Modelo de datos -> Establecer versión actual, compilación y ejecución, se producirá un error con el mencionado "Can "no encuentra el modelo para el almacén de origen" error. Vuelva a establecer el modelo en la versión 4, sin problemas, addPersistentStoreWithType. Alternativamente, si agrego la versión del modelo y no hago cambios, simplemente pase de la versión 4 a la 5 sin agregar ningún campo nuevo, sin problemas. Si luego intento pasar de 5 a 6, el error antes mencionado.

Este código está fallando tanto en el simulador como en el teléfono. Leí varias recetas que solicitan eliminar y volver a instalar la aplicación, que funciona tanto para el simulador como para el teléfono, pero me temo que cuando lo publique a usuarios reales, se romperá mi base instalada ya que no podrán eliminarse ni reinstalarse. - App Store los actualizará automáticamente.

Este código funcionó en versiones anteriores sin cambios de mi parte, por lo que mi capacidad para llegar hasta la versión 4. Recientemente actualicé la versión XCode 3.2.3 para iOS4, que puede tener algo que ver con esto.

¿Alguien más tiene este problema de repente ahora como yo? ¿Alguien ha logrado trabajar más allá de eso? Gracias.

PD: para los Googlers que se topan con esta página, aquí están todas las páginas relevantes que podría considerar leer, a continuación. Lamentablemente ninguno de estos resolvió mi problema.

ACTUALIZAR

Si bien esta no es una solución real, evita el escenario de un cliente que se estrella: simplemente elimine el archivo de base de datos:

if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) { // Delete file if ([[NSFileManager defaultManager] fileExistsAtPath:storeUrl.path]) { if (![[NSFileManager defaultManager] removeItemAtPath:storeUrl.path error:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } } if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) { // Handle the error. NSLog(@"Error: %@",error); NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } }

ACTUALIZACIÓN 2

Esto es lo que sucede cuando inspecciono VersionInfo.plist:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>NSManagedObjectModel_CurrentVersionName</key> <string>Profile 5</string> <key>NSManagedObjectModel_VersionHashes</key> <dict> <key>Profile</key> <dict> <key>Profile</key> <data> ZIICGgMBreuldkPXgXUhJwKamgwJzESM5FRTOUskomw= </data> </dict> <key>Profile 2</key> <dict> <key>Profile</key> <data> tEB7HrETWOSUuoeDonJKLXzsxixv8ALHOoASQDUIZMA= </data> </dict> <key>Profile 3</key> <dict> <key>Profile</key> <data> qyXOJyKkfQ8hdt9gcdFs7SxKmZ1JYrsXvKbtFQTTna8= </data> </dict> <key>Profile 4</key> <dict> <key>Profile</key> <data> lyWDJJ0kGcs/pUOModd3Q1ymDvdRiNXui4NCpLxDFSw= </data> </dict> <key>Profile 5</key> <dict> <key>Profile</key> <data> V4PyRK1ezj3xK1QFRCTVzGOqyJhEb7FRMzglrTsP0cI= </data> </dict> </dict> </dict> </plist>

Aquí está el código que escribí para inspeccionar mi modelo (nota que tuve que salir y agregar un codificador base64, ya que eso es lo que está en el archivo VersionInfo.plist)

if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) { NSDictionary *storeMeta = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:nil URL:storeUrl error:&error]; NSLog(@"%@",storeMeta); id someObj = [[storeMeta objectForKey:@"NSStoreModelVersionHashes"] objectForKey:@"Profile"]; NSLog(@"%@",someObj); NSLog(@"%@",[NSString base64StringFromData:someObj length:[someObj length]]);

Y aquí está la salida de depuración:

{ NSPersistenceFrameworkVersion = 310; NSStoreModelVersionHashes = { Profile = <97258324 9d2419cb 3fa5438c a1d77743 5ca60ef7 5188d5ee 8b8342a4 bc43152c>; SerializedMessage = <4530863c d943479a edfb4dfb 5059c28d d6137dc4 d1153d36 ed52be49 11074f13>; }; NSStoreModelVersionHashesVersion = 3; NSStoreModelVersionIdentifiers = ( ); NSStoreType = SQLite; NSStoreUUID = "823FD306-696F-4A0F-8311-2792825DC66E"; "_NSAutoVacuumLevel" = 2; } <97258324 9d2419cb 3fa5438c a1d77743 5ca60ef7 5188d5ee 8b8342a4 bc43152c> lyWDJJ0kGcs/pUOModd3Q1ymDvdRiNXui4NCpLxDFSw=

Como puede ver, la última línea que comienza con ''ly'' coincide con el perfil 4 en VersionInfo.plist ... por lo tanto, no veo ninguna razón por la que deba fallar. ¿Alguna otra idea?


Bueno, en mi caso sucedió exactamente lo mismo, estuve en iOS 7 y este problema me arregló la cabeza durante al menos una semana y, finalmente, encontré la solución que mejor me funciona. Para que funcione, tiene que agregar un valor extra en las opciones que se usan para agregar PersistentStore y luego ir (no estoy seguro acerca de otra versión de iOS, pero sí funcionará en iOS 7).

-(NSManagedObjectModel *)managedObjectModel { if (managedObjectModel != nil) { return managedObjectModel; } managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil]; return managedObjectModel; } -(NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (persistentStoreCoordinator != nil) { return persistentStoreCoordinator; } NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"ABC.sqlite"]; NSError *error = nil; persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] ini tWithManagedObjectModel:[self managedObjectModel]]; //Creating Lightweight migration. NSDictionary *options = @{ NSMigratePersistentStoresAutomaticallyOption:@YES ,NSInferMappingModelAutomaticallyOption:@YES ,NSSQLitePragmasOption: @{@"journal_mode": @"DELETE"} }; if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } return persistentStoreCoordinator; }


Gente

Para el registro, dejé de usar los datos básicos por completo. Mi código era complicado y, por las cuestiones anteriores, no es confiable. Ahora uso SQLLite directamente y estoy mucho más feliz. No puedo recomendar el uso de Core Data en ningún escenario.


He leído tu pregunta actualizada. Se está poniendo bastante desordenado con las versiones de modelo.

Debe probar y auditar la versión del modelo que la tienda existente realmente está solicitando e intentar enumerar todos los modelos disponibles en el paquete de aplicaciones en tiempo de ejecución.

Miro en el directorio de modelos de mis aplicaciones

NSString *modelDirectoryPath = [[NSBundle mainBundle] pathForResource:@"MyModel" ofType:@"momd"];

No estoy seguro si los desarrolladores normalmente hacen esto, pero mantengo las versiones de mi modelo con nombres diferentes ... así que tengo ahí:

  • VersionInfo.plist
  • MyModel.mom
  • MyModel2.mom

Los hashes de versión enumerados en VersionInfo.plist deberían ayudarlo a solucionar problemas. Busque el hash de versión requerido por el almacén persistente existente y vea si puede ubicarlo en los hashes de versión enumerados en VersionInfo.plist .

En realidad, no puedo ver una manera de escribir algún código que le pregunte al almacén persistente cuáles son los hashes de la versión de la entidad. El NSPersistentStoreCoordinator o el NSMigrationManger parecen estar haciendo eso en privado. es decir, verifican las versiones de entidad de tienda persistentes con el modelo con el que se carga la tienda.

Tenía otra mirada rápida, y está disponible en la tienda de metadatos. ¡Bonito y fácil!

NSError *error; NSURL *storeURL = [NSURL fileURLWithPath:[[self class] storePath]]; NSDictionary *storeMeta = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:nil URL:storeURL error:&error];

Y mirando en storeMeta obtengo una llave con

<CFString 0x7328050 [0x2724380]>{contents = "NSStoreModelVersionHashes"} = <CFBasicHash 0x7328340 [0x2724380]>{type = immutable dict, count = 5, entries => 0 : <CFString 0x7328110 [0x2724380]>{contents = "MyEntityNameOne"} = <CFData 0x73281b0 [0x2724380]>{length = 32, capacity = 32, bytes = 0x143325cf121239ce156af2e2a1aad7d9 ... 976977fdf29fc013} 1 : <CFString 0x7328130 [0x2724380]>{contents = "MyEntityNameTwo"} = <CFData 0x7328200 [0x2724380]>{length = 32, capacity = 32, bytes = 0x0ca6ecf1283d12bd3ca82af39b6b9f5d ... 149dd39a591e0c4d} ... }

Debería ser fácil iterar sobre el diccionario NSStoreModelVersionHashes y registrar los hashes de versión que su tienda requiere.

Haga coincidir manualmente eso con los disponibles en VersionInfo.plist y vea lo que falta. Quizás no haya un solo modelo que contenga todas las versiones requeridas de las entidades en su tienda persistente existente. ¿Eso podría suceder debido a ediciones (¿accidentales?) En el modelo antes o después de configurar una nueva versión del modelo?


Tuve el problema exacto de Esilver y encontré esta pregunta a través de Google. Sin embargo, la solución que funcionó para mí no estaba en ningún otro lugar en SO (que yo sepa), así que aquí va:

Si hay varias copias de sus archivos *.mom (modelos de objetos compilados) en su paquete, Core Data puede confundirse cuando intente migrar en su nombre.

Nuestro problema fue que cada archivo de modelo individual ( Data.xcdatamodel , Data_V1.xcdatamodel , Data_V2.xcdatamodel , etc.) no solo estaba dentro del directorio xcdatamodeld/ (que se incluyó como algo para compilar en el proceso de compilación), sino también cada archivo También se incluyó en la lista de "Fuentes de compilación".

Lo que esto significa es que el paquete resultante tenía dos conjuntos de archivos *.mom : uno dentro de xcdatamodeld/ y uno en el nivel superior. Creo que Core Data se volvió muy, muy confundido y condujo a este error. Eliminar cada archivo xcdatamodel de los "orígenes de compilación" y dejar el directorio xcdatamodeld solucionó el problema por nosotros (p. Ej., xcdatamodeld la xcdatamodeld automática en funcionamiento nuevamente). ¡Espero que esto ayude!