Any help appreciated.
Xcode auto updated to 8... I am Targeting IOS 9.3
Have all of the code converted across but one thing is now breaking, I have tried various suggestions in similar questions! My fetch request that was previously working is now breaking.
My goal is to get a distinct list. The app crashes on the line:
let results = try context.fetch(fetchRequest)
With the error described in the console as:
Could not cast value of type 'NSKnownKeysDictionary1' (0x10fd29328) to 'MyApp.BodyType' (0x10eebc820).
Here is the function
func getBodyTypes() {
let context = ad.managedObjectContext
let fetchRequest = NSFetchRequest<BodyType>(entityName: "BodyType")
fetchRequest.propertiesToFetch = ["name"]
fetchRequest.returnsDistinctResults = true
fetchRequest.resultType = NSFetchRequestResultType.dictionaryResultType
do {
let results = try context.fetch(fetchRequest)
for r in results {
bodyTypes.append(r.value(forKey: "name") as! String)
}
} catch let err as NSError {
print(err.debugDescription)
}
}
If the line below is hidden it doesn't break, but then i don't get what i want!
fetchRequest.resultType = NSFetchRequestResultType.dictionaryResultType
I understand i could use all of the results (4300) and loop through them as a bandaid fix, but this doesn't feel like the correct way to fix this, especially as it was working before!
The trick is to make the generic more general - instead of <BodyType>
in your fetch request, use <NSFetchRequestResult>
:
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "BodyType")
The result of this fetch request is [Any]
, so you will need to cast to the appropriate dictionary type before using. Eg:
func getBodyTypes() {
let context = ad.managedObjectContext
// 1) use the more general type, NSFetchRequestResult, here:
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "BodyType")
fetchRequest.propertiesToFetch = ["name"]
fetchRequest.returnsDistinctResults = true
fetchRequest.resultType = NSFetchRequestResultType.dictionaryResultType
do {
let results = try context.fetch(fetchRequest)
// 2) cast the results to the expected dictionary type:
let resultsDict = results as! [[String: String]]
for r in resultsDict {
bodyTypes.append(r["name"])
}
} catch let err as NSError {
print(err.debugDescription)
}
}
Note: NSFetchRequestResult
is a protocol, adopted by four types:
- NSDictionary
,
- NSManagedObject
,
- NSManagedObjectID
, and
- NSNumber
Typically, we're using it with an NSManagedObject
, such as your BodyType
. In this case, though, you're getting the dictionary type because of the statement:
fetchRequest.resultType = NSFetchRequestResultType.dictionaryResultType
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With