web-dev-qa-db-fra.com

'Un objet NSManagedObject de la classe' className 'doit avoir une description NSEntityDescription valide.' Erreur

J'ai créé une entité simple "CDWorkout" avec un attribut "nom" dans CDModel.xcdatamodeld. Le nom du conteneur dans AppDelegate est également 'CDModel'. La classe Codegen pour 'CDWorkout' est la catégorie/extension. Voici le code pour la classe CDWorkout:

class CDWorkout: NSManagedObject {

    class func createWorkout(workoutInfo : Workout, in context: NSManagedObjectContext) -> CDWorkout{
        let workout = CDWorkout(context: context)
        workout.name = "anyName"
        return workout
    }
}

la fonction createWorkout est appelée depuis un autre viewController avec un argument contextuel tel que container.viewContext mais se bloque immédiatement avec le message suivant:

Arrêt de l'application en raison d'une exception non interceptée 'NSInvalidArgumentException', raison: 'Un objet NSManagedObject de classe' Workout_Generator.CDWorkout 'doit avoir une description NSEntityDescription valide'

Qu'est-ce que j'ai oublié?

14
barola_mes

Le problème était que je n'avais pas vérifié Class Module: module de produit actuel pour CDWorkout Entity.

15
barola_mes

Dans mon cas, le même problème se trouvait dans le modificateur @objc dans l'en-tête généré automatiquement par la classe de données.

@objc(CachedMovie)
public class CachedMovie: NSManagedObject {

Je viens de retirer @objc(CachedMovie) et cela a commencé à fonctionner

8
Alexey

J'ai eu un problème mineur stupide qui a entraîné la même erreur. J'étais en train d'initialiser NSPersistentContainer avec un nom incorrect.

Il devrait porter le même nom que le fichier source portant l’extension .xcdatamodeld . par exemple. modelFileName.xcdatamodelId

let persistentContainer = NSPersistentContainer(name: "modelFileName")
4
nikdange_me

Je suis tombé sur le même message d'erreur lors de la tentative d'insertion/ajout d'un objet géré à partir d'une extension (SiriKit). Il semble y avoir eu un problème d'espace de noms de l'extension ne correspondant pas au fichier .xcdatamodeld, car je créais la description de l'entité à l'aide de MyClass.entity()

La combinaison qui a fonctionné pour moi était:

  • @objc(MyClass) en haut de chaque sous-classe NSManagedObject
  • Les entités du modèle de données utilisent "l'espace de nom global" par défaut, pas le "module de produit actuel".
  • Créez la description de l'entité en utilisant let entity = NSEntityDescription.entity(forEntityName: "MyClass", in: context)!
2
blwinters

 enter image description here dans votre fichier modeldataClass probablement le nom de la classe est incorrect car avant de changer le nom, quelque chose dans votre classe de noms

1
Papon Smc

il est facile de répondre à cette question. sans enlevé 

@objc(Workout)

la solution est sur documentaire Programmation des données de base sur "Nom de l’entité et Nom de la classe" . ici dans votre Xcode avant de le faire (Editor -> Create NSManagedObject SubClass) doit changer le nom de la classe des entités pour ajouter "MO", CoreData peut différencier le nom de la classe du nom de l’entité. et le

@objc(Workout) 

ne sera pas créé, donnez-nous celui-ci:

class CDWorkoutMO: NSManagedObject {

 class func createWorkout(workoutInfo : Workout, in context: NSManagedObjectContext) -> CDWorkoutMO {
    let workout = CDWorkoutMO(context: context)
    workout.name = "anyName"
    return workout
}
}

comme je le fais sur mon Xcode

0
Zehana fayçal

Vous devez créer un nouveau NSManagedObject avant de pouvoir l'utiliser.

let workout = NSEntityDescription.insertNewObjectForEntityForName("CDWorkout",
    inManagedObjectContext: context) as! CDWorkout

vous pouvez maintenant définir le nom comme vous l'avez fait: workout.name = "any_name"

vous pouvez vous référer à Documentation CoreData pour plus d’informations sur CoreData

0
Taras Chernyshenko

L’erreur que j’ai faite est de changer le nom de l’entité et de la "Sous-classe NSManagedObject" générée sans mettre à jour le nom de la classe. Comment réparer:

  • ouvrir le fichier .xcdatamodeld
  • cliquez sur l'entité
  • ouvrir le panneau de droite
  • Aller à l'inspecteur de modèle de données
  • Modifier le nom du champ de texte Classe
0
Lucas

J'ai eu un problème similaire dans la pile CoreData avec NSManagedObjectModel fabriqué à partir de code Swift. Le problème se trouvait dans mauvaise valeur pour l'attribut NSEntityDescription.managedObjectClassName. Le préfixe Swift module a été oublié.

Configuration correcte:

let entity = NSEntityDescription()
entity.name = PostEntity.entityName // `PostEntity`
entity.managedObjectClassName = PostEntity.entityClassName // `MyFrameworkName.PostEntity`
entity.properties = [....]

Où: entityName et entityClassName définis comme ceci.

extension NSManagedObject {

    public static var entityName: String {
        let className = NSStringFromClass(self) // As alternative can be used `self.description()` or `String(describing: self)`
        let entityName = className.components(separatedBy: ".").last!
        return entityName
    }

    public static var entityClassName: String {
        let className = NSStringFromClass(self)
        return className
    }

}
0
Vlad

J'essayais d'ajouter CoreData à un projet existant et j'ai renommé beaucoup de choses. Je me suis retrouvé avec plusieurs .xcdatamodeld sans le savoir. La solution consistait à supprimer .xcdatamodeld et à générer NSManagerObject, puis à le recréer.

0
Daniel Carlos