J'ai créé un modèle Core Data dans xcode 3.2 et, après la mise à niveau dans Xcode 4.2, j'ai ensuite ajouté une nouvelle entité de la sous-classe NSManagedObject (reportez-vous à la nouvelle entité).
D'abord, ça a l'air bizarre parce que ce n'est pas dans le même groupe que l'ancien. Voici la photo sur mon xcode 4.2 (AlkitabDB est celui créé dans xcode 3.2, EndeDB est le nouveau de la version actuelle de xcode (4.2):
Seconde chose, je l’ai laissée telle quelle, puis j’ai accédé à la deuxième entité (la nouvelle) de la même manière que la première entité (l’ancienne) et l’erreur telle qu’appelée apparaît.
Voici l'erreur:
2012-01-16 21:13:38.496 iHuria[55953:207] Unresolved error Error Domain=NSCocoaErrorDomain Code=134100 "The operation couldn’t be completed. (Cocoa error 134100.)" UserInfo=0x8829cd0 {metadata=<CFBasicHash 0x882a370 [0x1839b38]>{type = immutable dict, count = 7,
entries =>
2 : <CFString 0x8829b90 [0x1839b38]>{contents = "NSStoreModelVersionIdentifiers"} = <CFArray 0x8829ff0 [0x1839b38]>{type = immutable, count = 0, values = ()}
4 : <CFString 0x8829bc0 [0x1839b38]>{contents = "NSPersistenceFrameworkVersion"} = <CFNumber 0x8829770 [0x1839b38]>{value = +320, type = kCFNumberSInt64Type}
6 : <CFString 0x8829bf0 [0x1839b38]>{contents = "NSStoreModelVersionHashes"} = <CFBasicHash 0x882a080 [0x1839b38]>{type = immutable dict, count = 1,
entries =>
0 : <CFString 0x882a010 [0x1839b38]>{contents = "AlkitabDB"} = <CFData 0x882a030 [0x1839b38]>{length = 32, capacity = 32, bytes = 0xd02ac5f8be6ab0b39add450aca202ac0 ... 3d45d462998d2ccd}
}
7 : <CFString 0x10e3aa8 [0x1839b38]>{contents = "NSStoreUUID"} = <CFString 0x8829e60 [0x1839b38]>{contents = "4F2EE7FF-463B-4055-BBED-8E603CDBDF59"}
8 : <CFString 0x10e3948 [0x1839b38]>{contents = "NSStoreType"} = <CFString 0x10e3958 [0x1839b38]>{contents = "SQLite"}
9 : <CFString 0x8829c40 [0x1839b38]>{contents = "NSStoreModelVersionHashesVersion"} = <CFNumber 0x6b1c7c0 [0x1839b38]>{value = +3, type = kCFNumberSInt32Type}
10 : <CFString 0x8829c70 [0x1839b38]>{contents = "_NSAutoVacuumLevel"} = <CFString 0x882a0c0 [0x1839b38]>{contents = "2"}
}
, reason=The model used to open the store is incompatible with the one used to create the store}, {
metadata = {
NSPersistenceFrameworkVersion = 320;
NSStoreModelVersionHashes = {
AlkitabDB = <d02ac5f8 be6ab0b3 9add450a ca202ac0 ebd1e860 cbb578c2 3d45d462 998d2ccd>;
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers = (
);
NSStoreType = SQLite;
NSStoreUUID = "4F2EE7FF-463B-4055-BBED-8E603CDBDF59";
"_NSAutoVacuumLevel" = 2;
};
reason = "The model used to open the store is incompatible with the one used to create the store";
}
J'ai déjà recherché la solution et découvert que je devais supprimer l'application du simulateur et l'exécuter à nouveau, mais cela n'a pas fonctionné. Est-ce que quelqu'un connaît une solution à ce problème? S'il vous plaît aider.
La suppression de l'application n'est parfois pas le cas! Suggérez, votre application a déjà été publiée! Vous ne pouvez pas simplement ajouter une nouvelle entité à la base de données et continuer - vous devez effectuer une migration!
Pour ceux qui ne veulent pas creuser dans la documentation et qui cherchent une solution rapide:
Versioned core data model
sélectionnez votre nouvelle version du modèle de données pour le modèle de données actuelAppDelegate
et trouvez où est créé le persistentStoreCoordinator
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
nil
par @{NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES}
(fourni dans le code commenté de cette méthode).P.S. Cela s'applique uniquement à la migration légère. Pour que votre migration soit considérée comme une migration légère, vos modifications doivent être limitées à cette bande étroite:
Pour Swift 4
coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true])
Supprimez l'application du simulateur et effectuez un nettoyage de votre projet. Cela devrait éclaircir ces questions. Assurez-vous de ne pas exécuter le débogueur lorsque vous supprimez l'application, sinon elle ne sera pas supprimée correctement.
Si vous voulez vous assurer qu'il est parti, consultez le répertoire Users/INSERT_YOUR_USER_HERE/Library/Application Support/iPhone Simulator/
du dossier de votre application, sous la version que vous exécutez.
Note: Ceci est pour le développement seulement. Pour la production, vous devez implémenter une sorte de migration. Google "Migration de données de base", la migration légère étant la plus simple.
Ajoutez simplement l'attribut Options lors de la création de persistentStoreCoordinator dans le fichier AppDelegate.m pour la méthode de données principale, comme indiqué ci-dessous.
OBJECTIF-C
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil)
{
return _persistentStoreCoordinator;
}
NSLog(@"persistentStoreCoordinator___");
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"MyApp.sqlite"];
NSMutableDictionary *options = [[NSMutableDictionary alloc] init];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
NSLog(@"persistentStoreCoordinator___2");
return _persistentStoreCoordinator;
}
rapide
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
var failureReason = "There was an error creating or loading the application's saved data."
// MAIN LINE OF CODE TO ADD
let mOptions = [NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true]
do {
try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: mOptions)
} catch {
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error as NSError
let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
abort()
}
return coordinator
}
Il avait résolu mon problème ..
Answer: Supprimez l'application du simulateur, effectuez un nettoyage et reconstruisez votre projet.
Remarque: Lorsque vous apportez des modifications à la définition de Core Data, supprimez l'application installée sur le périphérique physique ou le simulateur, nettoyez le projet et reconstruisez à nouveau.
Oui. Une fois que vous supprimez une application sur un périphérique physique et que vous le reconstruisez, cela fonctionne.
Pour Swift, dans AppDelegate.Swift, trouvez la ligne
try coordinator!.addPersistentStoreWithType(NSXMLStoreType, configuration: nil, URL: url, options: nil )
et le remplacer par
try coordinator!.addPersistentStoreWithType(NSXMLStoreType, configuration: nil, URL: url, options: [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true])
Je viens de passer plusieurs jours à combattre cette erreur, ainsi que les plantages de mergedModelFromBundles et à obtenir l'erreur "Impossible de fusionner des modèles avec deux entités différentes nommées *".
Il se trouve que le problème fondamental était que Xcode ne supprimait pas les anciennes ressources des périphériques et que j'avais d'anciennes versions de mon modèle de données (fichiers .mom) qui étaient à l'origine de conflits. C'est pourquoi la suppression de l'application a résolu le problème sur l'un de mes appareils.
Après avoir trouvé cet article de blog via une autre SO réponse, j'ai rendu mon application plus tolérante vis-à-vis des anciens modèles en modifiant cette ligne qui recherche TOUS les fichiers .mom:
NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
à cela, qui ne regarde que dans le répertoire Filters:
NSString *path = [[NSBundle mainBundle] pathForResource:@"Filters" ofType:@"momd"];
NSURL *momURL = [NSURL fileURLWithPath:path];
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];
J'ai utilisé recursivePathsForResourcesOfType de this so question : pour vous aider à comprendre cela en enregistrant tous les fichiers .mom dans l'application:
NSArray *momPaths = [self recursivePathsForResourcesOfType:@"mom" inDirectory:[[NSBundle mainBundle] resourcePath]];
NSLog(@"All .mom files:%@",momPaths);
J'ai aussi utilisé iExplorer pour regarder les fichiers .mom superflus (je n'ai pas encore essayé de les supprimer).
La méthode ci-dessous était également utile. Cela montrait qu’une entité était dans le modèle fusionné renvoyé par [psc managedObjectModel] et n’existait plus dans aucun de mes modèles ou dans le magasin lui-même. C’est ce qui me laissait croire qu’un ancien modèle était mis en cache sur l’appareil lui-même que le bâtiment propre n’avait pas supprimé. La méthode enregistre chaque entité identique, modifiée, ajoutée ou supprimée du modèle. (écrit avec this SO answer comme point de départ):
- (BOOL)comparePersistentStore:(NSPersistentStoreCoordinator *)psc withStoreURL: (NSURL *)storeURL {
NSError *error = nil;
// Get the entities & keys from the persistent store coordinator
NSManagedObjectModel *pscModel = [psc managedObjectModel];
NSDictionary *pscEntities = [pscModel entitiesByName];
NSSet *pscKeys = [NSSet setWithArray:[pscEntities allKeys]];
//NSLog(@"psc model:%@", pscModel);
//NSLog(@"psc keys:%@", pscKeys);
NSLog(@"psc contains %d entities", [pscModel.entities count]);
// Get the entity hashes from the storeURL
NSDictionary *storeMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType
URL:storeURL
error:&error];
NSDictionary *storeHashes = [storeMetadata objectForKey:@"NSStoreModelVersionHashes"];
//NSLog(@"store metadata:%@", sourceMetadata);
NSLog(@"store URL:%@", storeURL);
NSLog(@"store NSStoreUUID:%@", [storeMetadata objectForKey:@"NSStoreUUID"]);
NSLog(@"store NSStoreType:%@", [storeMetadata objectForKey:@"NSStoreType"]);
NSSet *storeKeys = [NSSet setWithArray:[storeHashes allKeys]];
// Determine store entities that were added, removed, and in common (to/with psc)
NSMutableSet *addedEntities = [NSMutableSet setWithSet:pscKeys];
NSMutableSet *removedEntities = [NSMutableSet setWithSet:storeKeys];
NSMutableSet *commonEntities = [NSMutableSet setWithSet:pscKeys];
NSMutableSet *changedEntities = [NSMutableSet new];
[addedEntities minusSet:storeKeys];
[removedEntities minusSet:pscKeys];
[commonEntities minusSet:removedEntities];
[commonEntities minusSet:addedEntities];
// Determine entities that have changed (with different hashes)
[commonEntities enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) {
NSData *storeHash = [storeHashes objectForKey:key];
NSEntityDescription *pscDescrip = [pscEntities objectForKey:key];
if ( ! [pscDescrip.versionHash isEqualToData:storeHash]) {
if (storeHash != nil && pscDescrip.versionHash != nil) {
[changedEntities addObject:key];
}
}
}];
// Remove changed entities from common list
[commonEntities minusSet:changedEntities];
if ([commonEntities count] > 0) {
NSLog(@"Common entities:");
[commonEntities enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) {
NSData *storeHash = [storeHashes objectForKey:key];
NSEntityDescription *pscDescrip = [pscEntities objectForKey:key];
NSLog(@"\t%@:\t%@", key, pscDescrip.versionHash);
}];
}
if ([changedEntities count] > 0) {
NSLog(@"Changed entities:");
[changedEntities enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) {
NSData *storeHash = [storeHashes objectForKey:key];
NSEntityDescription *pscDescrip = [pscEntities objectForKey:key];
NSLog(@"\tpsc %@:\t%@", key, pscDescrip.versionHash);
NSLog(@"\tstore %@:\t%@", key, storeHash);
}];
}
if ([addedEntities count] > 0) {
NSLog(@"Added entities to psc model (not in store):");
[addedEntities enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) {
NSEntityDescription *pscDescrip = [pscEntities objectForKey:key];
NSLog(@"\t%@:\t%@", key, pscDescrip.versionHash);
}];
}
if ([removedEntities count] > 0) {
NSLog(@"Removed entities from psc model (exist in store):");
[removedEntities enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) {
NSData *storeHash = [storeHashes objectForKey:key];
NSLog(@"\t%@:\t%@", key, storeHash);
}];
}
BOOL pscCompatibile = [pscModel isConfiguration:nil compatibleWithStoreMetadata:storeMetadata];
NSLog(@"Migration needed? %@", pscCompatibile?@"no":@"yes");
return pscCompatibile;
}
utilisation: appelé avant d'ajouter chaque magasin à NSPersistentStoreCoordinator:
[self comparePersistentStore:self.psc withStoreURL:self.iCloudStoreURL];
_iCloudStore = [self.psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:self.iCloudStoreURL
options:options
error:&localError];
Chaque fois que vous modifiez la définition de Core Date, vous devez supprimer les applications installées sur le périphérique physique ou le simulateur.
Product
-> Clean
La solution la plus simple qui a fonctionné pour moi dans Swift 2.1, Xcode 7 est la suivante:
Supprimez l'application du simulateur (Cmd + Maj + H pour accéder à l'écran d'accueil. Appuyez longuement sur l'application, cliquez sur croix, comme vous le feriez pour supprimer une application de votre téléphone).
Cmd + Shift + H à nouveau pour arrêter la danse des applications
Retournez à votre projet et recommencez
J'ai eu ce problème lors de l'écriture/lecture de Core Data avec 2 entités mises en place. La suppression de l'application et la réexécution du programme ont résolu le problème.
Si vous utilisez Swift.
Suivez la réponse de @Stas et insérez les options, à la place de nil, dans votre délégué d'application:
let myOptions = [NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true]
if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: myOptions, error: &error) == nil {
Je viens de supprimer le fichier [Simulator App Folder]/Document/*.sqlite
après avoir apporté des modifications aux entités et cela a fonctionné. Et bien sûr, le fichier .sqlite contient toutes les données et structures stockées qui seront perdues.
Supprimez une application du simulateur, nettoyez un code et exécutez .it fonctionne correctement .il peut vous aider.
Essayez "Réinitialiser le contenu et les paramètres" dans le simulateur. A travaillé pour moi après la suppression de l'application et de la construction propre
J'ai rencontré le même problème avec mon application (pas encore publié dans l'App Store).
Voici comment je l'ai corrigé:
(3) fut l'étape qui l'a finalement fait fonctionner correctement. J'espère que cela t'aides!
Si vous apportez des modifications à votre modèle Core Data, vous devez fournir une stratégie de migration qui indique à Core Data comment adopter des objets persistants existants (créés par vos utilisateurs avec la version actuellement publiée) dans le nouveau modèle.
Pour certains scénarios, Core Data peut déduire automatiquement le mappage de l’ancien modèle sur le nouveau. Pour des modifications plus complexes, vous devrez peut-être implémenter une logique effectuant la migration.
Pour plus de détails, reportez-vous à la section Guide de programmation de la migration des données et du modèle de données de base .
Mettre à jour
Cette réponse ici sur Stack Overflow couvre les bases de la migration légère de Core Data et contient également du code pour vous aider à démarrer.
Bien que vous puissiez parfois simplement supprimer l'application du périphérique lors de la modification du schéma dans le modèle d'objet géré, dans certains cas, cela n'est pas possible, par exemple. parce que vous avez déjà publié votre application avec un vieux schéma.
Si tel est le cas, vous devez prendre en charge la migration des anciennes données vers le nouveau schéma:
versioning du modèle de données de base et migration des données
Vous devrez migrer le modèle Core Data à l'aide de la migration. Chaque fois que vous modifiez le modèle, vous le rendez incompatible avec le versioning. Attachez-vous, c'est un sujet un peu poilu.
Tout d’abord, les fichiers xcdatamodeld
ne doivent figurer que dans l’ensemble xcdatamodel
. Vos sous-classes doivent PAS être dans le xcdatamodeld
. Déplacez ceux-ci. Il y a de fortes chances qu'ils confondent le compilateur.
Deuxièmement, l'erreur indique que Core Data ne peut pas trouver votre modèle. Avez-vous créé des données et ensuite touché le modèle? Si c'est le cas, vous êtes dans un état incohérent et vous devez résoudre ce problème en supprimant les données (ce que Philippe a suggéré) ou en lançant vos modifications du modèle BACK.
Ce problème se produit généralement en raison de incompatibilité entre la version sur laquelle la base de données a été créée. L'approche générale à ce problème consiste à supprimer l'application et la réinstaller. Mais dans votre cas, les versions de DB sont complètement différentes sur Xcode 3.2 et 4.2. Il vaut donc mieux utiliser la même version de Xcode pour DB.
J'ai eu ce problème - j'ai d'abord réinitialisé mon simulateur puis nettoyé le projet et reconstruit. Et puis ça marche.
Lorsque vous modifiez des données de base (ajout d'un champ à une table, suppression d'un champ, etc.), le fichier sqlite du dossier du document d'applications doit être synchronisé avec votre schéma.
Ce fichier n'est pas écrasé par défaut, ce fichier doit être régénéré.
Suivez ces étapes:
Allez dans le dossier indiqué par NSURL. (Ce chemin peut être trouvé dans le message d'exception généré par l'application avant la panne.) Exemple:/Utilisateurs // Bibliothèque/Application Support/iPhone Simulator // Applications // Documents
supprimer ou renommer le fichier sqlite
Cela garantira que le schéma et Xcode sont synchronisés.
J'obtenais l'erreur mais la raison pour laquelle j'ai eu l'erreur était due à ce qui suit.
À l'origine, j'avais une entité nommée "Entrée" et une ligne était enregistrée pour cette entité dans la base de données. J'ai ensuite ajouté une autre entité nommée "Personne" et après l'ajout, je suis allée construire et j'ai eu l'erreur. J'ai donc résolu le problème en supprimant l'entité "Personne" puis en construisant l'application, supprimé la ligne qui se trouvait dans "Entrée", puis fermé l'application. J'ai ensuite supprimé complètement l'application de mon téléphone, puis je l'ai reconstruite et tout a bien fonctionné. Vous ne savez pas quelle étape a corrigé le problème (suppression de la ligne ou de l'application), mais j'espère que si vous cherchez une solution, cela vous aidera. :)
Edit: Oh, et si vous vous inquiétiez de la suppression de votre nouvelle entité (dans mon cas, "Personne") pour reconstruire l'application, rappelez-vous que vous pouvez la récupérer par la suite en utilisant CMD + Z!