When trying to downcast a fetched NSManagedObject to it's correct subclass StoryPhotoTrack
in my (Swift) unit tests, I get a runtime error: Could not cast value of type 'StoryPhotoTrack_StoryPhotoTrack_' (0x7fbda4734490) to 'StoryPhotoTrack' (0x11edd1b08).
Here's my failing / crashing test:
func testFetchingStoryWithCastingInvolved() {
let story : StoryPhotoTrack? = storyFetcher.fetchAnyStoryPhotoTrack()
XCTAssertNotNil(story, "should be a story") // works
let definitlyAStory : StoryPhotoTrack = story! // works
let object : NSManagedObject = story as NSManagedObject! // works
println(NSStringFromClass(definitlyAStory.dynamicType)) // prints 'StoryPhotoTrack_StoryPhotoTrack_'
let downCastedStory : StoryPhotoTrack = object as! StoryPhotoTrack // -> error: "Could not cast..."
XCTAssertNotNil(downCastedStory, "should still be a story")
}
// StoryFetcher.swift
func fetchAnyStoryPhotoTrackVia_ObjectiveC_Fetcher() -> StoryPhotoTrack? {
let object = StoryPhotoTrack.fetchAnyStoryPhotoTrackInContext(moc)
return object as StoryPhotoTrack?
}
The actual fetching is done in Objective-C:
// StoryPhotoTrack+Fetching.m
+ (StoryPhotoTrack *)fetchAnyStoryPhotoTrackInContext:(NSManagedObjectContext *)moc
{
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"StoryPhotoTrack"];
NSArray *storyTracks = [moc executeFetchRequest:request error:nil];
return (StoryPhotoTrack *)[storyTracks lastObject];
}
I assume, it has something to do with Swift's namespaces. Seems like my StoryPhotoTrack class is actually called StoryPhotoTrack_StoryPhotoTrack_
.
I tried renaming the class names of my core data entities with projectName-prefixes (as suggested here), but that did not help. I tried both my main target module name and my test target module name, none of them worked.
What am I doing wrong?
edit: seems like I overlooked SO questions like How to test Core Data properly in Swift, so it seems, this issue is known, but not easy to solve. Is it really the best way to create a separate framework for your Core Data Model?