Подтвердить что ты не робот

Ошибка выполнения executeFetchRequest: элемент NSArray не соответствует типу элемента Swift Array

Я тестирую swift с помощью CoreData, и я создал следующий код:

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)")

    }

}

Когда я запускаю:

Contact.execute()

Затем компилятор выдает эту ошибку:

fatal error: NSArray element failed to match the Swift Array Element type

когда я пытаюсь получить значения из массива:

 let firstContact = result[0] as Contact

Я думаю, проблема в executeFetchRequest. В Objective-c возвращаемый тип executeFetchRequest равен NSArray. Теперь в Swift тип возврата - [AnyObject]?.

Я попытался применить результат [AnyObject]? к NSArray, но Xcode сказал:

 Cannot convert the expression type '[AnyObject]?' to type 'NSArray' 

Что я делаю неправильно?

Я использую: Xcode 6.0 (6A313) GM и OSX 10.9.4

Update:
-----------

Если я получаю executeFetchRequest результат как необязательный массив и использую [NSManagedObject] вместо [Contact], он работает.

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:
-----------

Эта проблема возникает, когда экземпляры объектов не загружаются с использованием класса NSManagedObject. Существует несколько разных причин, почему это происходит, и все они сосредоточены на "Core Data не могут найти класс, который вы указали для этого объекта в строке класса в модели данных".

Среди возможностей:
- Вы указали неверный пакет для своего класса Swift
- Вы забыли указать класс
- Вы неправильно написали имя

В моем случае я забыл указать класс, как показывает POB в ее ответе.

4b9b3361

Ответ 1

Я смог воспроизвести ваше сообщение об ошибке в консоли. Вы получите это сообщение, потому что вы не правильно установили имя класса сущности в редакторе модели основных данных (см. Рисунок ниже).

enter image description here

Как только вы закончите, вы сможете использовать свой оригинальный код с Contact subClass. Вы можете узнать больше о Core Data и пространствах имен здесь.

Ответ 2

В моем случае я изменил модуль как "Текущий модуль продукта" внутри Редактора модели основных данных. Он начал работать отлично для меня. введите описание изображения здесь

Ответ 3

Я думаю, ваша проблема в том, что executeFetchRequest возвращает дополнительный массив, а не массив. Вам нужно развернуть его.

if let result: [Contact]? = context.executeFetchRequest(fetch, error: nil) as? [Contact] {

    let firstContact = result[0]

    println("/(firstContact.name)")
    println("/(firstContact.email)")
}

Ответ 4

Я думаю, что его плохая идея установить префикс вашего целевого имени, например this Потому что, если вы хотите переместить вашу модель в другое приложение или изменить имя таргетинга, вы в конечном итоге измените его,

Итак, есть и другой способ. Если вы посмотрите, как xcode генерирует основные объекты данных сейчас, поскольку @A_man сказал, что вам нужно установить текущий модуль в редакторе и использовать @objc() следующим образом:

import CoreData

@objc(Contact)
class Contact: NSManagedObject {
    @NSManaged var name: String?
    @NSManaged var email: String?
}

И поле должно быть необязательным, поскольку они могут быть nil

Ответ 5

Проверьте класс и модуль в Entity из Data Model Inspector и установите имя класса как имя и модуль объекта как "Текущий модуль продукта", Имя класса и модуль