Search code examples
core-datansmanagedobjectswift3xcode8any

Swift 3 Value of type 'Any' has no member 'valueForKey'


I am writing a test program with Core Data using Swift 3.0 in Xcode 8. Problem is that when I try to receive any data from NSManagedObject like this:

    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 {
}

the line

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

marked with error

Value of type 'Any' has no member 'valueForKey'

So question is how to get from type Any a single record data? P.S. if it is possible, without casting to AnyObject type because it is leading to this

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

which also has a error:

Cannot invoke 'value' with an argument list of type '(String)'

And I want to do it in proper way. Thank you!

UPDATE

I found a solution (thanks to Vadian), but I doubt it is right one:

    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 {
}

I am still searching for a right way to do this.


Solution

  • fetch returns [Any]. You need to downcast the type to the actual type, in this case [NSManagedObject].

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

    The forced downcast is safe because according to the fetch request it's guaranteed that the return type is NSManagedObject.