web-dev-qa-db-fra.com

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

Je duplique une application existante Objective-C TV Show vers une nouvelle version Swift utilisant Xcode 6.1 et j'ai quelques 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 définies (pour 'Compiler les 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 non trouvée, en utilisant NSManagedObject par défaut.

Quelques commentaires:

Lors de l'enregistrement dans Core Data, j'utilise la méthode de contexte parent-enfant pour autoriser le threading en arrière-plan. Je le fais en configurant 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...
})
90
JimmyJammed

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

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

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

1.
Version fonctionnant jusqu’à Xcode 7 beta

Up to XCode7 b3

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

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

Vous devez supprimer le texte "Module de produit actuel" dans Module!

From Xcode7 beta 3

2.
Vous devriez également suivre la recommandation fréquente d'inclure

@objc(Show)

juste au-dessus de votre classe.

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

.
Assurez-vous également de transtyper l'objet 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
171
Mundi

Mise à jour de Swift 2/XCODE 7:

Ce problème (voir mon commentaire du 3 avril sur cette réponse également) est résolu dans Swift 2 et XCode 7 version bêta de Apple. Donc vous n'avez plus besoin de @objc(myEntity) in Swift comme l'a répondu Mundi ou si vous utilisez "MyAppName." Avant le nom de votre classe. Il cessera de fonctionner. supprimez-les, mettez simplement Classnom dans Fichier et sélectionnez Current Working Module sous la forme Module et bravo!

Selecting current working module

Mais pour ceux qui utilisent @objc(myEntity) in Swift (comme moi), vous pouvez utiliser cette autre solution à la place qui fonctionne sans problème.

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

Setting the class

Voici. Module.Class est le modèle pour CoreData dans Swift et XCode 6. Vous aurez également besoin de la même procédure pour utiliser Stratégie personnalisée. class dans Model Policy ou dans CoreData. Remarque: dans l'image, le nom et la classe doivent être Car et MyAppName.Car (ou quel que soit le nom de votre entité). Ici, User est une faute de frappe.

67
khunshan

Lors de l'utilisation de Xcode 7 et de Swift uniquement, je devais réellement supprimer@objc(MyClass) à partir de mon auto-généré NSManagedObject sous-classe (générée à partir de Editor > Create NSManagedObject Subclass...).

36
Santa Claus

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

Module of managed object type set to "Current Product Module" in Xcode 7

Supprimer le paramètre du module afin qu'il soit vide ou supprimer l'arrêt complet afin que le nom de la classe dans la configuration ne soit que File sont des actions équivalentes, car chacune provoque l'autre modification. L'enregistrement de cette configuration supprimera l'erreur décrite.

Module of managed object set to be blank in Xcode 7

12
Duncan Babbage

Dans Xcode 6.1.1, il n'est pas nécessaire d'ajouter l'attribut @objc car l'entité de base est un sous-ensemble d'une classe objc (NSManagedObject) (voir Compatibilité Swift Type . Dans CoreData, nom complet de Module.Class Notez que le nom du module correspond à 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 la cible . nom .

9
Jim Malak

Avec xCode 7 et Swift 2.0, vous n'avez pas besoin d'ajouter @objc (NameOfClass), il suffit de modifier les paramètres de l'entité dans l'onglet "Afficher l'inspecteur de modèle de données" comme ci-dessous -

Nom - "Nom de votre entité"

Classe - "Votre nom d'entité"

Module - "Module de produit actuel"

enter image description here

Le fichier de code pour la classe d'entité sera comme (dans mon code Entity is Family) -

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

5
Himanshu Mahajan

N'oubliez pas de remplacer PRODUCT_MODULE_NAME avec le nom de votre module de produit.

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

3
Kof

Vous devez également utiliser (au moins avec Xcode 6.3.2) Module.Class lors de la conversion, par exemple: En supposant que votre module (c'est-à-dire le nom du produit) est Food 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 d'une entité dans l'éditeur de modèle de données (Nom: Fruit, Classe: Food.Fruit)
  • Lors de l'accès à l'entité dans le code (i.e.Swift), convertissez-la avec Module.class (par exemple, Food.Fruit).
2
Wizkid

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 par défaut, pas "Module de produit actuel"
1
WSJ

Modifier le nom de la classe d'entité dans l'éditeur de modèle de données pour qu'il corresponde à la classe en question et ajouter @objc(NameOfClass) au fichier de chaque droit NSManagedObject au-dessus de la déclaration de classe a résolu ce problème pour moi lors du test d'unité.

1
user3269767

Ce qui a fonctionné pour moi (Xcode 7.4, Swift) est de changer le nom de la classe en <my actual class name>.<entity name> dans l'inspecteur d'entités, zone "Classe".

Mon initiateur de la sous-classe d'objets gérés, ressemble à ceci:

    convenience init(<properties to init>) {
    let entityDescr = NSEntityDescription.entityForName("<entity class name>", inManagedObjectContext: <managed context>)
    self.init(entity: entityDescr!, insertIntoManagedObjectContext: <managed context>)}
    //init properties here
0
mark