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...
})
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
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!
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
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 simplementClass
nom dans Fichier et sélectionnezCurrent Working Module
sous la forme Module et bravo!
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:
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.
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...).
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
.
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.
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 .
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"
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
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.
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:
J'ai également rencontré un problème similaire, suivez ces étapes pour résoudre:
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é.
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