web-dev-qa-db-fra.com

Impossible de créer un NSPersistentStoreCoordinator avec un modèle nil

J'ai eu ma première tentative chez Core Data et je reçois le message d'erreur suivant lors de l'exécution de mon code sur mon appareil, mais cela fonctionne correctement sur le simulateur.

* Arrêt de l'application en raison d'une exception non interceptée 'NSInvalidArgumentException', motif: 'Impossible de créer un NSPersistentStoreCoordinator avec un modèle nul'

Certaines de mes méthodes pouvant être à l'origine du problème:

    - (NSManagedObjectContext *)managedObjectContext
{
    if (__managedObjectContext != nil)
    {
        return __managedObjectContext;
    }

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

/**
 Returns the managed object model for the application.
 If the model doesn't already exist, it is created from the application's model.
 */
- (NSManagedObjectModel *)managedObjectModel
{
    if (__managedObjectModel != nil)
    {
        return __managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"RugbyOnTv" withExtension:@"momd"];
    __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];    
    return __managedObjectModel;
}

/**
 Returns the persistent store coordinator for the application.
 If the coordinator doesn't already exist, it is created and the application's store added to it.
 */
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (__persistentStoreCoordinator != nil)
    {
        return __persistentStoreCoordinator;
    }

    NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"RugbyOnTV.sqlite"];

    NSURL *storeUrl = [NSURL fileURLWithPath:storePath];

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];    
    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];

    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();
    }    

    return __persistentStoreCoordinator;
}


    - (NSString *)applicationDocumentsDirectory {

        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
        return basePath;
    }

MODIFIER

J'ai copié et collé la méthode managedObjectContext (ci-dessous) à partir de CoreDataBooks d'Apple et cela fonctionne maintenant .. Vous ne savez vraiment pas pourquoi

- (NSManagedObjectModel *)managedObjectModel {
    if (managedObjectModel != nil) {
        return managedObjectModel;
    }
    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];    
    return managedObjectModel;
}
95
Dominic Williams

J'ai eu exactement le même message d'erreur que le message original. Je me débattais avec ça pendant des heures… .. C’était cette ligne dans mon AppDelegate.m.

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"[same with name of xcdatamodeld]" withExtension:@"momd"];

Pour tous ceux qui recherchent ce message d'erreur et trouvent ce fil .... essayez-le d'abord.

Vous devez vous assurer que là où il est écrit [même chose avec le nom de xcdatamodeld] ... que c’est !!! Pour une raison quelconque, le mien avait mon nom de projet dedans et non le nom du modèle de données.

Changé et cela a fonctionné tout de suite .....

Merci à Rock & Muller pour sa contribution ... vous m'avez économisé des jours !!

Gaz.

157
Gareth Lloyd

d'abord vérifier:

NSLog(@"%@", [self managedObjectModel]);

Si vous obtenez une valeur nulle, le problème est peut-être là

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"RugbyOnTv" withExtension:@"momd"];

Alors, essayez de changer @ "momd" par @ "mom"

54
D33pN16h7

J'ai rencontré un problème étrange avec Xcode 4.3.2 et iOS 5.

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"NAME_OF_THE_MODEL" withExtension:@"momd"];

renvoie une URL valide mais 

__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

renvoie un null NSManagedObjectModel. Mais après avoir vérifié la documentation , il semble que NSManagedObjectModel ait besoin d’un fichier dans lequel NAME_OF_THE_MODEL.momd est un répertoire contenant un fichier NAME_OF_THE_MODEL.mom. Changer l'URL en 

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"NAME_OF_THE_MODEL" withExtension:@"mom" subdirectory:@"NAME_OF_THE_MODEL.momd"];

puis fonctionne. Cela semble étrange que Xcode génère du code qui ne fonctionne pas avec lui-même ...

20
xster

J'ai eu ce problème et changer "maman" en "maman" n'a rien fait. Pour résoudre ce problème, je devais cliquer avec le bouton droit sur le fichier xcdatamodelId> afficher le contenu du paquet, puis supprimer le fichier caché .xcurrentversion.

P.S: Ce problème n’a commencé à se produire qu’après avoir changé le nom du fichier de modèle de données. 

19
JDx

Une autre source de cette erreur est que, parfois, Xcode n'inclut pas le modèle de données dans la construction.

Vérifiez les phases de construction de votre cible et assurez-vous que le fichier * .xcdatamodeld est inclus dans la section Compiler les sources.

13
Dave Wood

Ce qui est probablement arrivé, c’est que votre fichier xcdatamodeld du code source d’Apple est devenu un fichier xcdatamodel (sans le fichier d) et qu’ils ne sont donc pas considérés comme identiques.

Le moyen le plus rapide de résoudre ce problème consiste à sélectionner le fichier xcdatamodel dans le navigateur de votre projet et dans la barre de menus. 

Editor->Add Model Version...

et ajoutez une nouvelle version de votre modèle. Apportez toutes les modifications à la nouvelle version.

Cela fonctionne dans Xcode 5

9
Louis Cremen

Je le résous en ajoutant le fichier db au Copy Bundle Resources

Allez à la racine de votre projet >> sélectionnez votre cible >> Construire les phases >> Copier les ressources de l'ensemble. Assurez-vous que votre fichier xcdatamodeld a été ajouté ici. 

enter image description here

Aucune des solutions affichées n'a fonctionné pour moi. Donc, espérons que ce post aide quelqu'un. Mon application ne plante que dans la version finale. Leçon apprise. Toujours tester les versions de version! 

BTW, j'ai trouvé ce SO message le plus utile https://stackoverflow.com/a/6708837/951349 .

6
smileBot

j'ai eu le même problème avec @Dominic Williams

essayez de changer le nom du fichier momd ci-dessous (vous pouvez le trouver dans la méthode managedObjectModel par défaut), qui est identique au fichier [file name].xcdatamodeld que vous avez créé:

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"[same with name of xcdatamodeld]" withExtension:@"momd"];
6
rock

J'ai eu le même problème. La solution était un mélange de 2 réponses:

1) J'ai dû ajouter le paramètre "sous-répertoire" à l'appel URLForResource

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"DATAMODEL_NAME" withExtension:@"mom" subdirectory:@"DATAMODEL_NAME.momd"];

2) Pour une raison que je ne connais pas, le modèle de données n'a pas été inclus lors de la compilation du projet. Je devais l'ajouter manuellement dans "Construire les phases/Compiler les ressources".

Avec une seule des solutions ci-dessus, mon application n'a pas fonctionné.

5

La solution au problème dont vous parlez est simple. Modifiez l'extension du fichier en "maman" au lieu de "momd" dans l'URL du modèle. Terminé.

4
pfuri

Je résous le problème sans changer de code.

J'ajoute le ModelName.xcdatamodeld via File-> Add File au lieu de faire glisser le fichier dans le Xcode.

 NSString *path=@"ModelName";

NSURL *modelURL = [NSURL fileURLWithPath:[path stringByAppendingPathExtension:@"momd"]];

model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
4
Chris So

J'ai essayé toutes les solutions ici et aucune d'entre elles n'a fonctionné. Mon problème est apparu après avoir renommé le projet. Apparemment, Xcode continue de rechercher l'ancien fichier momd au mauvais endroit pendant la compilation. 

Pour tous ceux qui ont essayé toutes les solutions ci-dessus sans succès, essayez de vérifier le chemin complet de votre fichier .xcdatamodeld. C'est ce qui a fonctionné pour moi. 

4
XCool

J'ai eu le même problème, cela fonctionnait bien sur iOS6 mais pas sur iOS5 . Voici comment je l'ai résolu:

  1. Créez une nouvelle version du modèle dans xcode. (sélectionnez le .xcdatamodeld, ouvrez le menu Editeur et cliquez sur "Ajouter une version du modèle ...")
  2. Compilez et assurez-vous que la nouvelle version fonctionne.
  3. Définir l'ancien comme version actuelle. ("Actuel" dans l'inspecteur de fichier pour le .xcdatamodeld sous Modèle de données de base versioned)
  4. Supprimer la référence au fichier .xcdatamodeld dans xcode
  5. Faites un clic droit sur le fichier .xcdatamodeld dans le Finder et choisissez "Afficher le contenu du paquet".
  6. Supprimer le nouveau .xcdatamodel que vous ne voulez pas
  7. Rajoutez le .xcdatamodeld dans xcode
  8. Compiler et sourire

(C’est là que j’ai trouvé comment supprimer une version de modèle: Comment supprimer une ancienne version de modèle de données inutilisée dans Xcode )

4
fredrik

Si quelqu'un est bloqué à cause du même problème. Assurez-vous que vous avez correctement lié la base de données (car vous avez peut-être copié le code directement à partir d'un exemple) .
Il suffit de mettre à jour le nom de la base de données dans managedObjectModel et persistentStoreCoordinator methods dans AppDelegate.

1
nomann

J'ai eu ce problème de nulle part après avoir supprimé l'application générée dans le ~/Library/Application Support/iPhone Simulator. D'une manière ou d'une autre, les générations suivantes ont échoué dans le simulateur et sur les périphériques. Cela faisait longtemps que rien n’avait changé avec CoreData, mais cela aurait échoué avec le Cannot create an NSPersistentStoreCoordinator with a nil model. J'ai essayé quelques choses ci-dessus et rien n'a fonctionné.

Je pouvais voir le dossier momd généré avec le fichier maman à l'intérieur. L'application du simulateur pouvait voir les deux, mais le fichier sqlite n'a pas été généré.

Ce qui a résolu le problème, c’était d’ajouter un attribut à une entité de mon fichier xcdatamodeld dans Xcode, puis de le supprimer immédiatement. J'espérais que Xcode régénérerait tout ce qui était à l'origine du problème et que cela semblait fonctionner. Vous ne comprenez toujours pas ce qui n'allait pas, mais mon application fonctionne à nouveau dans le simulateur et les périphériques.

1
Alistair McMillan

Je sais que cela ne résout pas votre problème, mais j'ai rencontré ce problème hier qui m'a tourmenté pendant des heures. La solution affichée par @Dominic Williams m'a donné une ArrayIndexOutOfBoundsException (quel que soit l'équivalent d'Objective-C).

Je ne suis pas encore très bon avec Objective-C/Xcode mais je travaille sur une application iOS que notre société a (principalement) développée en externe. Malheureusement, ils oubliaient souvent comment utiliser un clavier et utilisaient indifféremment les majuscules ou les propriétés orthographiées de manière incorrecte, mais étaient trop paresseux pour revenir en arrière et les modifier. Ils avaient utilisé une lettre majuscule dans le nom du projet xcode là où ce n'était pas censé être (notre nom de produit n'utilise pas de majuscule) et j'ai dû revenir en arrière et changer chaque occurrence de cette lettre majuscule en minuscule. ; qui comprenait le nom du projet, le fichier de données principal, des centaines de variables, etc.

Quoi qu'il en soit, une fois que j'ai fait cela, j'ai rencontré cette erreur et aucune solution ne la réparait pour moi. Je m'étais assuré que tous les noms d'URL étaient corrects, le projet nettoyé, l'application désinstallée, le téléphone redémarré, etc. sans résultat. J'ai abandonné et j'ai éteint mon Mac et je suis rentré chez moi pour la journée. À ma grande surprise, je suis rentré ce matin et tout semblait bien fonctionner!

Je ne sais pas pourquoi cela a fonctionné, mais si vous êtes bloqué, essayez de redémarrer votre Mac.

1

Je cherchais une réponse depuis des heures et rien ne fonctionnait. Mais alors j'ai soudain trouvé cet article . En conséquence, le problème était de configurer le contrôleur racine dans cette partie de AppDelegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    ListViewController *rootView = (ListViewController *)self.window.rootViewController;
    rootView.managedObjectContext = self.managedObjectContext;
    return YES;
}

En fait, vous devez définir le contrôleur racine qui déléguera votre connexion CoreData. Et dans mon cas, un contrôleur TabBar était connecté à d'autres vues. Mon contrôleur racine de vue targuée était donc défini comme étant TabBar et provoquait une erreur. j'ai changé

ListViewController *rootView = (ListViewController *)self.window.rootViewController;

à

ListViewController *rootView = (ListViewController *)self.window.superview;

et tout a fonctionné.

1
kokoko

J'ai eu le même problème, c'est-à-dire 

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyModel" withExtension:@"momd"];

a renvoyé la valeur nil, car aucun fichier .momd n'a été généré.

La raison en était que, dans le répertoire de l'application (par exemple, MyGreatApp/MyGreatApp.app), xcode avait copié le fichier MyModel.xcdatamodeld au lieu de générer le fichier MyModel.momd à partir du fichier MyModel.xcdatamodeld (à l'aide de momc).

La solution consistait à supprimer la référence à MyModel.xcdatamodeld dans le navigateur de projet XCode et à la faire glisser dans le projet à partir du Finder. Après que xcode se soit rendu compte qu'il fallait le compiler en un .momd.

1

De mon côté, le problème était que j'avais changé le cas de quelques caractères dans le nom de la base de données.

Lors du démarrage d'un nouveau projet, Xcode configure automatiquement tout depuis le nom du projet. Si vous appelez votre projet "Rugbyontv" et que vous décidez plus tard de changer pour "RugbyOnTV" et effectuez une recherche et un remplacement, le résultat serait cassé. (Nous remercions Rob d'avoir souligné que le nom est sensible à la casse)

1
Brian Gerfort

Si votre projet fonctionne sur le simulateur mais pas sur le périphérique, essayez d'exécuter la release-build sur votre périphérique au lieu de la version de débogage.

Sélectionnez votre projet -> Produit -> Éditer le schéma -> Configurer la construction [DEBUG -> RELEASE]

Maintenant, relancez le projet, cela fonctionnera.

0
stackr

Je viens d'avoir un problème similaire lors de la mise à niveau d'IOS5 à IOS6. Il s'avère que c'était un problème sensible à la casse avec le nom du modèle. 

Pas sûr que cela aide quelqu'un. 

0
Troy

Voir aussi ce fil: Le test unitaire ne trouve pas le fichier de modèle Core Data

Cela m'a aidé à résoudre le problème - ce qui ne s'est produit qu'avec le test unitaire

0
Thorsten Niehues

Pour moi, le problème était dû au fait que je copiais mon modèle collé d'un projet de bac à sable vers mon projet actuel. Assurez-vous toujours de générer votre modèle à partir du projet dans lequel il est utilisé. 

0
FujiRoyale

Je suis également confronté à ce problème, mais lorsque je modifie le fichier ModelName.xcdatamodeld, il fonctionne. Je pense donc que le fichier ModelName.xcdatamodeld n'est pas ajouté correctement, alors vérifiez et nettoyez l'application et exécutez-la.

0
Nadella Ravindra

J'ai rencontré la même erreur quand je ai renommé le fichier .xcdatamodel de xcode et que j'ai changé le nom renommé dans le délégué de l'application partout où c'était nécessaire, mais j'ai toujours eu la même erreur. Aucune des procédures suggérées n'a fonctionné pour moi.

Ensuite, j'ai ouvert le dossier dans Finder et trouvé un fichier supplémentaire .xccurrentversion avec un fichier .xcdatamodel. Je l'ai ouvert dans l'application TextEdit et j'ai changé ceci:

<dict>
    <key>_XCCurrentVersionName</key>
    <string>Your_Renamed_Model_FileName.xcdatamodel</string>
</dict>

Je l'utilise avec Xcode 6.4, OSX Yosemite 10.10.1

J'espère que ça aide!

0
NeverHopeless

Après avoir résolu le problème de nommage, l'erreur est restée. Cela a ensuite fonctionné après le redémarrage de Xcode 5. Cela pourrait automatiquement faire la même chose que certaines des suggestions de liens manuels proposées ici.

0
EthanP

D'accord, je vais d'abord dire à une demi-solution, cela fonctionnera si vous réinstallez l'application (dans un simulateur ou un dispositif de débogage). Mais ce n'est pas une vraie solution pour vous. Par exemple, si vous mettez à jour votre application, ne le faites PAS ou votre nouvelle version risque de tomber en panne car les utilisateurs ne le réinstalleraient pas. Ils utiliseront alors le bouton de mise à jour. 

Si j'ai bien compris, ce problème survient généralement lorsque vous modifiez le nom du fichier de modèle de données. La raison pourrait être comme ça:
. Lorsque vous exécutez l'application pour la première fois, elle crée un fichier de modèle de données dans un ensemble d'applications, tel que "data_model_1". Cette création ne se produit que pour la première fois.
. Lorsque vous mettez à jour le nom du fichier et que vous exécutez l'application à nouveau, elle ne pourra pas être trouvée car il y a toujours un fichier "data_model_1" mais vous lui demandez de rechercher "data_model_2". Comment peut-il trouver, il ne l'a pas encore créé et ne le fera que si vous n'installez pas l'application avec un nouveau nom de fichier. 

Donc, s'il s'agit de la première version de votre application et que la réinstallation sur un simulateur ou un appareil ne nuit pas à votre projet, allez-y. Sinon, consultez Guide de gestion des versions de modèles de données Core et de la migration de données sur la bibliothèque de développement iOS, c'est peut-être ce dont vous avez besoin. 

Edit: Si la réinstallation ne fonctionne pas, essayez d’abord de désinstaller, puis de nettoyer le projet, puis de tout fermer, de rouvrir le projet et de lancer + exécuter. Cela devrait fonctionner.

0
kubilay