Swift 3 Значение типа «Любой» не имеет члена «valueForKey»

Я пишу тестовую программу с Core Data, используя Swift 3.0 в Xcode 8. Проблема в том, что когда я пытаюсь получить какие-либо данные из NSManagedObject следующим образом:

    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Entity")
request.returnsObjectsAsFaults = false
do {
    let entityTableInCoreData = try newPrivateQueueContext.fetch(request)
    for i in entityTableInCoreData {
        if let a = i.valueForKey("b") as? String {
            print(a)
        }
    }
} catch {
}

линия

if let a = i.valueForKey("b") as? String {

отмечен с ошибкой

Значение типа Any не имеет члена valueForKey.

Итак, вопрос в том, как получить из типа Any данные одной записи? P.S. если это возможно, без приведения к типу AnyObject, потому что это приводит к этому

if let a = (i as AnyObject).value("b") as? String {

который также имеет ошибку:

Не удается вызвать «значение» со списком аргументов типа «(String)»

И я хочу сделать это должным образом. Благодарю вас!

ОБНОВИТЬ

Я нашел решение (спасибо Vadian), но я сомневаюсь, что оно правильное:

    do {
    let entityTableInCoreData = try newPrivateQueueContext.fetch(request)
    for i in entityTableInCoreData {
        print("Record")
        //print(i)
        if let a = i as? NSManagedObject {
            print("a: \(a.value(forKey: "a"))")
        }
    }

} catch {
}

Я все еще ищу правильный способ сделать это.


person Alex    schedule 15.09.2016    source источник
comment
Нет, это тоже ошибка:   -  person Alex    schedule 15.09.2016
comment
Тип «Любой» не имеет элементов нижнего индекса   -  person Alex    schedule 15.09.2016
comment
Где это сделать? выборка (запрос) как [String: AnyObject]   -  person Alex    schedule 15.09.2016
comment
Насколько я понимаю, entityTableInCoreData — это просто массив NSManagedObjects. Так что мне просто нужно взять данные из него.   -  person Alex    schedule 15.09.2016
comment
fetch возвращает [Any]. Вы должны понизить тип до [NSManagedObject] или [NSFetchRequestResult] или, если вы используете подкласс NSManagedObject, что рекомендуется, до [<Name Of Subclass>]   -  person vadian    schedule 15.09.2016
comment
Можете ли вы проверить обновление моего ответа? Это вы говорили?   -  person Alex    schedule 15.09.2016
comment
В основном да, но я хотел добавить as! [NSManagedObject] к строке fetch. Необязательная привязка if let a = i не нужна, поскольку в этом случае гарантируется, что возвращаемый тип — NSManagedObject.   -  person vadian    schedule 15.09.2016
comment
Спасибо! Но я оставлю это необязательным, просто чтобы быть на 100% защищенным. Но вы считаете, что это правильный и правильный способ чтения данных из Core Data и NSManagedObject?   -  person Alex    schedule 15.09.2016
comment
Да, это так. Что касается дополнительной привязки, вы защищены на 100%. fetch может возвращать массив Dictionary или массив NSManagedObject в зависимости от запроса. Если вы не передадите явно return value is dictionary, вы получите 100% NSManagedObject. Это один из немногих случаев, когда необязательная привязка используется неправильно, потому что она избыточна.   -  person vadian    schedule 15.09.2016


Ответы (1)


fetch возвращает [Any]. Вам нужно понизить тип до фактического типа, в данном случае [NSManagedObject].

let entityTableInCoreData = try newPrivateQueueContext.fetch(request) as! [NSManagedObject]

Принудительное приведение вниз безопасно, поскольку в соответствии с запросом на выборку гарантируется, что возвращаемый тип — NSManagedObject.

person vadian    schedule 15.09.2016