Je teste Swift avec CoreData et j'ai créé le code suivant:
import UIKit
import CoreData
class Contact: NSManagedObject {
@NSManaged var name: String
@NSManaged var email: String
class func execute(){
let appDel:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
let context:NSManagedObjectContext = appDel.managedObjectContext!
let entityDescripition = NSEntityDescription.entityForName("Contact", inManagedObjectContext: context)
let contact = Contact(entity: entityDescripition!, insertIntoManagedObjectContext: context)
contact.name = "john Apleesee"
contact.email = "[email protected]"
context.save(nil)
let fetch:NSFetchRequest = NSFetchRequest(entityName: "Contact")
var result = context.executeFetchRequest(fetch, error: nil) as [Contact]
let firstContact = result[0] as Contact // <<-- error !
println("\(firstContact.name)")
println("\(firstContact.email)")
}
}
Quand je cours:
Contact.execute()
Ensuite, le compilateur renvoie cette erreur:
fatal error: NSArray element failed to match the Swift Array Element type
quand j'essaie d'obtenir des valeurs de array:
let firstContact = result[0] as Contact
Je suppose que le problème est dans executeFetchRequest
. Sur Objective-c le type de retour de executeFetchRequest
est une NSArray
. Maintenant sur Swift le type de retour est un [AnyObject]?
.
J'ai essayé de convertir le résultat [AnyObject]?
en NSArray
, mais Xcode a déclaré:
Cannot convert the expression's type '[AnyObject]?' to type 'NSArray'
Qu'est-ce que je fais mal?
J'utilise: Xcode 6.0 (6A313) GM et OSX 10.9.4
Mettre à jour:
-----------
Si j'obtiens executeFetchRequest
résultat sous la forme d'un tableau facultatif et que j'utilise [NSManagedObject]
au lieu de [Contact]
, cela fonctionne.
if let result: [NSManagedObject]? = context.executeFetchRequest(fetch, error: nil) as? [NSManagedObject] {
let firstContact: NSManagedObject = result![0]
let name = firstContact.valueForKey("name") as String
let email = firstContact.valueForKey("email") as String
println("\(name)")
println("\(email)")
}
Update2:
-----------
Ce type de problème se produit lorsque les instances d'entité n'ont pas été chargées à l'aide de votre classe NSManagedObject. Cela se produit pour différentes raisons. Toutes se concentrent sur "Core Data n'a pas pu trouver la classe spécifiée pour cette entité sur la ligne de classe dans le modèle de données".
Parmi les possibilités:
- Vous avez spécifié le mauvais paquet pour votre classe Swift
- Vous avez oublié de spécifier la classe
- Vous avez mal orthographié le nom
Dans mon cas, j’ai oublié de spécifier la classe comme le montre POB dans sa réponse.
J'ai pu reproduire votre message d'erreur dans la console. Vous recevez ce message parce que vous n'avez pas correctement défini le nom de votre classe d'entité dans l'éditeur de modèle de données principal (voir l'image ci-dessous).
Une fois cela fait, vous pourrez utiliser votre code original avec Contact
subClass. Vous pouvez en apprendre plus sur les données de base et les espaces de noms ici .
Je pense que c'est une mauvaise idée de définir le préfixe de votre nom de cible comme this Parce que si vous souhaitez déplacer votre modèle dans une autre application ou changer le nom de la cible, vous devrez le modifier à nouveau.
Donc, il y a un autre moyen. Si vous regardez maintenant comment xcode génère des entités de données de base, @A_man a déclaré que vous deviez définir le module actuel dans editor et utiliser @objc () comme ceci:
import CoreData
@objc(Contact)
class Contact: NSManagedObject {
@NSManaged var name: String?
@NSManaged var email: String?
}
Et le champ doit être facultatif car ils peuvent être nuls
Vérifiez la classe et le module dans Entity à partir de l'inspecteur de modèles de données et définissez le nom de la classe comme nom d'entité et le module comme "Module produit actuel" Nom de la classe et module