I’ve got the following CoreData query in Swift 5.8. The compiler sees the type of vals
as [Value]
. vals.count == 1
. When I try to get the first element, the app crashes with “Fatal error: NSArray element failed to match the Swift Array Element type. Expected Value but found NSManagedObject”
let req = NSFetchRequest<Value>(entityName: "Value")
req.predicate = NSPredicate(format: "name == %@", inKey)
let moc = Model.shared.container.viewContext
let vals = try moc.fetch(req)
if vals.count == 1
{
let v = vals[0] // Error here
return v.value
}
class Value : NSManagedObject {
@NSManaged var name : String
@NSManaged var value : String
}
If I print the description of vals
in the debugger, I get:
Printing description of vals:
([MissionClock.Value]) vals = 1 value {
[0] = 0x0000600000f782d0
}
Fatal error: NSArray element failed to match the Swift Array Element type
Expected Value but found NSManagedObject
Oh and btw, if I try to create the fetch request like this (as shown here) I get an error:
let req: NSFetchRequest<Value> = Value.fetchRequest()
Cannot assign value of type 'NSFetchRequest<any NSFetchRequestResult>' to type 'NSFetchRequest<Value>'
What’s going on here?
Update: I had some stuff set up incorreclty with Core Data, and once I sorted it out, everything worked. Everything doesn’t quite make sense, but the questions are all Core Data-related and not really Swift.
I had defined the Value
class in Swift, but the fetchRequest()
method wasn’t creating the right thing because I had forgotten to specify the class in the XCDataModel. After wasting time defining it in Objective-C (I thought I was doing something wrong in Swift), I finally realized I needed to specify the app’s module name when defining it in Swift (but not Obj-C). What’s still perplexing is that I have to cast the result of Value.fetchRequest() as! NSFetchRequest<Value>
, even though the example I found online doesn’t. Seems the Swift interface could’ve been written to return the non-generic type.