Why is the class wrong for NSFetchRequest?

Posted by Stephen Furlani on Stack Overflow See other posts from Stack Overflow or by Stephen Furlani
Published on 2010-05-28T18:54:42Z Indexed on 2010/05/29 18:42 UTC
Read the original article Hit count: 323

Hello,

I am working with an undocumented API (Osirix) and I have a sister-question to the one I posted here.

I am having trouble loading objects from a managed object context.

With loading from API, using their instance of _context and _model

2010-05-28 14:05:13.588 OsiriX[44012:a0f] Entity: Study
2010-05-28 14:05:13.589 OsiriX[44012:a0f] EntityClassName: DicomStudy
2010-05-28 14:05:13.589 OsiriX[44012:a0f] ClassName: DicomStudy

With loading from Fetch Request (and my own instance of _context, and _model)

2010-05-28 14:19:09.956 rcOsirix[44431:7a03] Entity: Study
2010-05-28 14:19:09.957 rcOsirix[44431:7a03] EntityClassName: DicomStudy
2010-05-28 14:19:09.958 rcOsirix[44431:7a03] ClassName: NSManagedObject

output given by:

NSLog(@"Entity: %@",[[item entity] name]);
NSLog(@"EntityClassName: %@", [[item entity] managedObjectClassName]);
NSLog(@"ClassName: %s", class_getName(object_getClass([item class])));

So it is obvious that even though the Entity thinks it is a DicomSeries - it is not. It is just a NSManagedObject. DicomSeries has some "hard-coded" KVC stuff that I ran into a problem with in my other question.

I'm pursuing a different line of reasoning in this thread - with the loading of the objects.

The following is their code:

- (NSManagedObjectModel *)managedObjectModel
{
    if (managedObjectModel) return managedObjectModel;

    NSMutableSet *allBundles = [[NSMutableSet alloc] init];
    [allBundles addObject: [NSBundle mainBundle]];
    [allBundles addObjectsFromArray: [NSBundle allFrameworks]];

    managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL: [NSURL fileURLWithPath: [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"/OsiriXDB_DataModel.mom"]]];
    [allBundles release];

    return managedObjectModel;
}

- (NSManagedObjectContext *) managedObjectContextLoadIfNecessary:(BOOL) loadIfNecessary
{
    NSError *error = nil;
    NSString *localizedDescription;
    NSFileManager *fileManager;

    if( currentDatabasePath == nil)
        return nil;

    if (managedObjectContext)
        return managedObjectContext;

    if( loadIfNecessary == NO) return nil;

    fileManager = [NSFileManager defaultManager];

    [persistentStoreCoordinator release];

    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: self.managedObjectModel];

    managedObjectContext = [[NSManagedObjectContext alloc] init];
    [managedObjectContext setPersistentStoreCoordinator: persistentStoreCoordinator];

    NSURL *url = [NSURL fileURLWithPath: currentDatabasePath];

    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error])
    {
        NSLog(@"********** managedObjectContextLoadIfNecessary FAILED: %@", error);
        localizedDescription = [error localizedDescription];
        error = [NSError errorWithDomain:@"OsiriXDomain" code:0 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:error, NSUnderlyingErrorKey, [NSString stringWithFormat:@"Store Configuration Failure: %@", ((localizedDescription != nil) ? localizedDescription : @"Unknown Error")], NSLocalizedDescriptionKey, nil]];
    }

    [[managedObjectContext undoManager] setLevelsOfUndo: 1];
    [[managedObjectContext undoManager] disableUndoRegistration];

    // This line is very important, if there is NO database.sql file
    [self saveDatabase: currentDatabasePath];

    return managedObjectContext;
}

This is my code:

NSManagedObjectModel* DataModule::managedObjectModel()
{
if (_managedObjectModel) return _managedObjectModel;

    NSMutableSet *allBundles = [[NSMutableSet alloc] init];
    [allBundles addObject: [NSBundle mainBundle]];
    [allBundles addObjectsFromArray: [NSBundle allFrameworks]];

_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL: [NSURL fileURLWithPath: [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"/OsiriXDB_DataModel.mom"]]];

    [allBundles release];

return [_managedObjectModel retain];
}

...
        NSError *error = nil;
        [_storeCoordinator release];

        _storeCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: managedObjectModel()];

        _context = [[NSManagedObjectContext alloc] init];
        [_context setPersistentStoreCoordinator: _storeCoordinator];

        NSURL *url = [NSURL fileURLWithPath: [[NSString alloc] initWithCString:_DBPath.c_str()]];

        if (url == nil) { [pool release]; _loadLock = false; return nil; }

        if (![_storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error])
        {
            NSLog(@"********** managedObjectContextLoadIfNecessary FAILED: %@", error);
            NSString *localizedDescription = [error localizedDescription];
            error = [NSError errorWithDomain:@"OsiriXDomain" code:0 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:error, NSUnderlyingErrorKey, [NSString stringWithFormat:@"Store Configuration Failure: %@", ((localizedDescription != nil) ? localizedDescription : @"Unknown Error")], NSLocalizedDescriptionKey, nil]];

            //Exit Failure
            [pool release]; _loadLock = false; return nil;
        }

        [[_context undoManager] setLevelsOfUndo: 1];
        [[_context undoManager] disableUndoRegistration];
...

I am including all the same frameworks.... but _allBundles isn't even used to create the managedObjectModel so I don't know what it's supposed to do except load them into memory so that the mom can look at them while loading.

Totally lost.

Help!

Why would objects returned by my FetchRequest with the same Entity come out as NSManagedObjects and not DicomStudys? I'm including DicomStudy.h so it should see the object during creation of the model, context, and fetch request.

[request setEntity: [[managedObjectModel() entitiesByName] objectForKey:@"Study"]];

Thanks in advance,

-Stephen

© Stack Overflow or respective owner

Related posts about c++

Related posts about objective-c