CoreData: avertissement: impossible de charger la classe nommée

Je duplique une application Objective-C TV Show existante dans une nouvelle version de Swift à l’aide de Xcode 6.1 et rencontre des problèmes avec CoreData.

J’ai créé un modèle de 4 entités, créé leur sous-classe NSManagedObject (dans Swift) et tous les fichiers ont les cibles d’application appropriées (pour ‘Comstack Sources’).

Je reçois toujours cette erreur chaque fois que j’essaie d’insérer une nouvelle entité:

CoreData: avertissement: impossible de charger la classe nommée ‘Shows’ pour l’entité ‘Shows’. Classe introuvable, à la place de NSManagedObject par défaut.

Quelques commentaires:

Lorsque vous enregistrez dans Core Data, j’utilise la méthode contextuelle parent-enfant pour autoriser les threads d’arrière-plan. Je le fais en configurant le ManagedObjectContext en utilisant:

lazy var managedObjectContext: NSManagedObjectContext? = { // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail. let coordinator = self.persistentStoreCoordinator if coordinator == nil { return nil } var managedObjectContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.MainQueueConcurrencyType) managedObjectContext.persistentStoreCoordinator = coordinator return managedObjectContext }() 

et en sauvegardant les données en utilisant:

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in var context = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType) context.parentContext = self.managedObjectContext! ...rest of core data saving code here... }) 

Cet avertissement est l’un des problèmes auxquels nous devons faire face pendant que les détails de la mise en œuvre de Swift sont en train d’être réglés. L’avertissement se produit de manière frauduleuse, c’est-à-dire que votre configuration peut fonctionner même si vous ne suivez pas les étapes décrites ci-dessous.

J’ai pu m’en débarrasser dans la plupart des cas en veillant à ce que la classe soit correctement définie dans l’éditeur de modèles . Contrairement à beaucoup d’autres publications SOF (y compris les réponses à cette question), la suggestion d’inclure le nom du module (comme MyApp.Shows ) ne m’a pas aidé.

Assurez-vous de vérifier ces trois éléments:

1.
Version qui fonctionne jusqu’à Xcode 7 beta 3

Jusqu'à XCode7 b3

Notez que j’ai corrigé le nom de votre entité au singulier le plus approprié.

Version qui fonctionne pour Swift 2.0 dans Xcode 7.1
(Devrait fonctionner pour Xcode 7 beta 4 et supérieur)

Vous devez supprimer le texte “Current Product Module” dans le module!

De Xcode7 beta 3

2.
Vous devriez également suivre les recommandations fréquentes pour inclure

 @objc(Show) 

juste au dessus de votre classe.

Remarque : Si vous utilisez Xcode 7 beta 4 ou une version ultérieure, cette étape est facultative.

3.
Veillez également à convertir l’object géré créé dans la classe appropriée, car la valeur par défaut serait simplement NSManagedObject .

 var newShow = NSEntityDescription.insertNewObjectForEntityForName("Show", inManagedObjectContext: context) as Show 

Mise à jour SWIFT 2 / XCODE 7:

Ce problème (voir mon commentaire du 3 avril sur cette réponse également) est résolu dans la version bêta de Swift 2 et XCode 7 par Apple. Vous n’avez donc plus besoin de @objc(myEntity) dans Swift, comme l’a répondu Mundi ou en utilisant ” MyAppName. ” Avant le nom de votre classe. Il cessera de fonctionner. Donc, supprimez-les, mettez simplement le nom de la Class dans le fichier et sélectionnez Current Working Module tant que module et applaudissements!

Sélection du module de travail actuel

Mais pour ceux qui utilisent @objc(myEntity) dans Swift (comme moi), vous pouvez utiliser cette autre solution au lieu de cela.

Dans la classe correcte de xcdatamodel, cela devrait ressembler à ceci:

Définir la classe

Voici. Module.Class est le modèle pour CoreData dans Swift et XCode 6. Vous aurez également besoin de la même procédure lors de l’utilisation de la classe de stratégie personnalisée dans la stratégie de modèle ou d’autres éléments CoreData. Une note: Dans l’image, le nom et la classe doivent être Car et MyAppName.Car (ou quel que soit le nom de votre entité). Ici, l’ User est une faute de frappe.

En utilisant Xcode 7 et purement Swift, j’ai dû supprimer @objc(MyClass) de ma sous-classe NSManagedObject (générée à partir de Editor > Create NSManagedObject Subclass ... ).

Dans Xcode 7 beta 2 (et je crois 1), dans le modèle de configuration, un nouvel object géré de type File est défini sur le module de Current Product Module et la classe de l’object est affichée dans la configuration sous la forme .File .

Module du type d'objet géré défini sur

La suppression du paramètre du module pour qu’il soit vide ou la suppression de l’arrêt complet pour que le nom de la classe dans la configuration ne soit que File sont des actions équivalentes, car chacune entraîne l’autre modification. L’enregistrement de cette configuration supprimera l’erreur décrite.

Module d'objet géré défini pour être vide dans Xcode 7

Dans Xcode 6.1.1, vous n’avez pas besoin d’append l’atsortingbut @objc car l’entité de base est un sous-ensemble d’une classe objc (NSManagedObject) (voir Compatibilité des types Swift . Dans CoreData, le nom complet de Module.Class est requirejs. nom est ce qui est défini dans Paramètres de construction -> Conditionnement -> Nom du module de produit Par défaut, il est défini sur $ (PRODUCT_NAME: c99extidentifier) ​​qui sera le nom de la cible .

Avec la version xCode 7 et Swift 2.0, vous n’avez pas besoin d’append @objc (NameOfClass), modifiez simplement les parameters de l’entité dans l’onglet “Afficher l’inspecteur de modèles de données” comme ci-dessous –

Nom – “Votre nom d’entité”

Class – “Votre nom d’entité”

Module – “Module Produit Actuel”

entrer la description de l'image ici

Le code du fichier de classe d’entité sera comme (dans mon code, l’entité est la famille) –

 import UIKit import CoreData class Family: NSManagedObject { @NSManaged var member : AnyObject } 

Cet exemple fonctionne bien dans mon application avec xCode 7.0 + swift 2.0

N’oubliez pas de remplacer PRODUCT_MODULE_NAME par le nom de votre module produit.

Lorsqu’une nouvelle entité est créée, vous devez accéder à l’inspecteur de modèles de données (dernier onglet) et remplacer PRODUCT_MODULE_NAME par le nom de votre module ou une erreur de class not found lors de la création du coordinateur de magasin persistant.

Vous devez également utiliser (au moins avec Xcode 6.3.2) Module.Class lors de l’exécution de votre dissortingbution, par exemple: En supposant que votre module (c’est-à-dire le nom du produit) est de la nourriture et que votre classe est Fruit

 let myEntity = NSEntityDescription.entityForName("Fruit", inManagedObjectContext: managedContext) let fruit = NSManagedObject(entity: myEntity!, insertIntoManagedObjectContext:managedContext) as! Food.Fruit 

Résumer:

  • Inclure le nom du module lors de la définition de l’entité dans l’éditeur de modèle de données (Nom: Fruit, Classe: Food.Fruit)
  • Lorsque vous accédez à l’entité dans le code (ieSWIFT), lancez-la avec Module.class (par exemple, Food.Fruit)

Modifier le nom de la classe d’entité dans l’éditeur de modèle de données pour correspondre à la classe en question et append @objc(NameOfClass) au fichier de chaque NSManagedObject juste au-dessus de la déclaration de classe a résolu ce problème pendant les tests unitaires.

J’ai également rencontré un problème similaire, suivez ces étapes pour résoudre:

  1. Le parent est NSManagedObject, pas NSObject
  2. Le module d’une entité est le module par défaut, pas le “module de produit actuel”

Ce qui a fonctionné pour moi (Xcode 7.4, Swift) est de changer le nom de la classe en . nom de . dans l’inspecteur d’entité, zone “Classe”.

Mon initiateur de la sous-classe d’object géré ressemble à ceci:

  convenience init() { let entityDescr = NSEntityDescription.entityForName("", inManagedObjectContext: ) self.init(entity: entityDescr!, insertIntoManagedObjectContext: )} //init properties here