web-dev-qa-db-fra.com

Impossible de trouver une sous-classe spécifique de NSManagedObject

Je travaille sur le développement d'une application avec Core Data. Quand j'ai créé une instance en utilisant:

let entity = NSEntityDescription.entityForName("User", inManagedObjectContext: appDelegate.managedObjectContext)
let user = User(entity: entity, insertIntoManagedObjectContext: appDelegate.managedObjectContext)

J'ai un avertissement dans le journal:

CoreData: warning: Unable to load class named 'User' for entity 'User'.  Class not found, using default NSManagedObject instead.

Comment pourrais-je le réparer?

Et une autre question, comment puis-je définir une méthode d'instance dans la sous-classe NSManagedObject?

Modifier:

J'ai spécifié la classe de l'entité comme dans la capture d'écran suivante:

enter image description here

131
MsrButterfly

Mise à jour pour Xcode 7 (final): Il n'est plus nécessaire d'ajouter le nom du module à la classe (comme dans Xcode 6 et les premières versions bêta de Xcode 7) . La documentation Apple implémentation des sous-classes d'objets gérés de données de base) a été mise à jour en conséquence.

L'inspecteur de modèle de données comporte désormais deux champs "Classe" et "Module" pour une entité:

enter image description here

Lorsque vous créez une sous-classe d'objet géré Swift pour l'entité, le champ "Module" est défini sur "Module produit actuel" et, avec ce paramètre, la création d'instances fonctionne à la fois dans l'application principale et dans l'unité. La sous-classe de l'objet géré doit pas être marquée de @objc(classname) (cela a été observé dans https://stackoverflow.com/a/31288029/1187415 ).

Sinon, vous pouvez vider le champ "Module" (il affichera "Aucun") et marquer les sous-classes d'objets gérés avec @objc(classname) (ceci a été observé dans https://stackoverflow.com/a/31287260/1187415 ).


Remarque: Cette réponse a été écrite à l'origine pour Xcode 6. Des modifications ont été apportées aux diverses versions bêta de Xcode 7 en ce qui concerne ce problème. Comme il s’agit d’une réponse acceptée avec de nombreux votes positifs et de liens, j’essaie de résumer la situation pour la version finale actuelle de Xcode 7.

J'ai fait mes propres "recherches" et lu toutes les réponses à cette question et à une question similaire CoreData: warning: Impossible de charger la classe nommée . Donc, l'attribution va à tous, même si je ne les énumère pas spécifiquement!


Réponse précédente pour Xcode 6 :

Comme indiqué dans la section Implémentation de sous-classes d'objets gérés de données de base , vous devez préfixer le nom de classe d'entités dans le champ Classe de l'inspecteur d'entités de modèle avec le nom de votre module, par exemple "MyFirstSwiftApp.User".

215
Martin R

Juste comme une note de côté. J'ai eu le même problème. Et tout ce que j'avais à faire, c'était d'ajouter @objc(ClassName) dans mon fichier de classe.

Exemple:

@objc(Person)
class Person { }

Et cela a résolu mon problème.

60
Christer

La réponse acceptée à cette question m'a aidé à résoudre le même problème, mais j'avais une mise en garde qui, à mon avis, pourrait être utile aux autres. Si le nom de votre projet (module) contient un espace, vous devez le remplacer par un trait de soulignement. Par exemple:

Entity: MyEntity Classe: My_App_Name.MyClass

30
Mannix

N'oubliez pas de retirer votre module:

enter image description here

16

Selon que vous utilisez App vs Tests, le problème peut être que l'application recherche <appName>.<entityName> et quand il est utilisé comme test, il ressemble à <appName>Tests.<entityName>. La solution que j'utilise actuellement (Xcode 6.1) consiste à NE PAS remplir le champ Class dans l'interface utilisateur CoreData et à le faire à la place dans le code.

Ce code détectera si vous exécutez l'application en tant que App vs Tests, utilisez le nom de module correct et mettez à jour le managedObjectClassName.

lazy var managedObjectModel: NSManagedObjectModel = {
    // The managed object model for the application. This property is not optional...
    let modelURL = NSBundle.mainBundle().URLForResource("Streak", withExtension: "momd")!
    let managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL)!

    // Check if we are running as test or not
    let environment = NSProcessInfo.processInfo().environment as [String : AnyObject]
    let isTest = (environment["XCInjectBundle"] as? String)?.pathExtension == "xctest"

    // Create the module name
    let moduleName = (isTest) ? "StreakTests" : "Streak"

    // Create a new managed object model with updated entity class names
    var newEntities = [] as [NSEntityDescription]
    for (_, entity) in enumerate(managedObjectModel.entities) {
        let newEntity = entity.copy() as NSEntityDescription
        newEntity.managedObjectClassName = "\(moduleName).\(entity.name)"
        newEntities.append(newEntity)
    }
    let newManagedObjectModel = NSManagedObjectModel()
    newManagedObjectModel.entities = newEntities

    return newManagedObjectModel
}()
9
Ludovic Landry

Si vous utilisez un trait d'union dans le nom de votre projet, tel que "My-App", utilisez un trait de soulignement à la place du trait d'union, tel que "My_App.MyManagedObject". En général, examinez le nom du fichier xcdatamodeld et utilisez le même préfixe que dans ce nom. C'est à dire. "Mon_App_1.xcdatamodeld" requiert le préfixe "Mon_App_1"

8
Rien

Cela peut aider ceux qui rencontrent le même problème. J'étais avec Swift 2 et Xcode 7 beta 2.

La solution dans mon cas était de commenter @objc(EntityName) dans EntityName.Swift.

5
enreas

J'ai eu le même avertissement, même si mon application semblait fonctionner correctement. Le problème était que lors de l'exécution Editor> Create NSManagedObject Subclass sur le dernier écran, j'ai utilisé l'emplacement de groupe par défaut, sans cibles affichées ni cochée, ce qui a enregistré la sous-classe dans le répertoire MyApp supérieur dans lequel se trouvait MyApp.xcodeproj.
L’avertissement a disparu lorsque j’ai changé le groupe afin qu’il se trouve dans le sous-dossier MyApp et que je vérifie la cible MyApp.

3
Daniel Ford

Soit dit en passant, indiquez ce que vous ajoutez comme préfixe: Mon application s'appelle "ABC-def" et Xcode a converti le "-" en "_".

Pour être sûr de regarder dans le Finder, trouvez vos fichiers de projet et voyez ce qu'il dit pour votre modèle de données (par exemple "ABC_def.xcdatamodeld") et utilisez ce qui y est écrit EXACTEMENT !!!

2
Mike

Les réponses ci-dessus ont été utiles. Ce contrôle de santé rapide peut vous faire gagner du temps. Allez dans Projet> Phases de construction> Compiler les sources et supprimez votre xcdatamodeld et vos fichiers de modèle avec le bouton "-", puis ajoutez-les de nouveau avec le bouton "+". Reconstruire - cela peut en prendre soin.

2
trevorgrayson

Les réponses ci-dessus m'ont aidé à résoudre différents problèmes liés à Objective-C (cela aidera peut-être quelqu'un):

Si vous restructurez les noms d'entités, n'oubliez pas de modifier également "Classe" dans "Panneau des utilitaires".

1
Vive

Les réponses ci-dessus m'ont aidé, mais cela peut aider quelqu'un. Si, comme moi, vous les avez faites et rencontrez toujours un problème, rappelez-vous simplement de "nettoyer votre projet". Pour XCode8, Produit> Nettoyer. Puis relancez-vous.

0
Olaolu Akinsete

Dans Xcode 7, les noms d'entité et de classe peuvent être identiques, mais Codegen doit être une définition de classe. Dans ce cas, il n'y aura aucun avertissement, etc. entrez la description de l'image ici

0
dcaric