objective-ccore-dataios5uimanageddocument

Override managedObjectModel in UIManagedDocument


I'm working with the new UIDocument features in iOS 5.0. I have an existing application that uses multiple different Data Models (momd files). According to the documentation for UIManagedDocument, you can override -(NSManagedObjectModel*)managedObjectModel to load a specific Data Model (the default is load all found data models merged together). Both data models have overlapping model names with different schemas, so this is not desirable in my case.

Relevant Apple Doc

So, the problem I have here in a simple sample, is that I can override the function, but I cannot assign it's result. It is both private, so _managedObjectModel cannot be accessed by the subclass; and, it is read-only, so self.managedObjectModel cannot be assigned..

I've looked for a UIManagedDocument example that does override managedObjectModel, but Apple doesn't appear to provide one.

I may be able to define a new instance variable _myManagedObjectModel and assign that. Then return that on the accessor I'm overriding. My concern is that may break some internal implementation of the UIManagedDocument that does not use the managedObjectModel accessor in preference for _managedObjectModel (which is seen often in Apples implementations...)

Seems like a straight forward problem and I suspect I'm just missing something really simple to allow a proper override.

//
//  DTNoteDocument.m
//  document-test
//
//

#import "DTNoteDocument.h"

@implementation DTNoteDocument

NSString * const kDataManagerModelName = @"Note";

-(NSManagedObjectModel*)managedObjectModel {

    if (_managedObjectModel != nil)
        return _managedObjectModel;

    NSBundle *bundle = [NSBundle mainBundle];
    NSString *modelPath = [bundle pathForResource:kDataManagerModelName ofType:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:[NSURL fileURLWithPath:modelPath]]; // compile error on this line, private variable cannot be assigned

    return _managedObjectModel;
}
@end

Header:

#import <UIKit/UIKit.h>

@interface DTNoteDocument : UIManagedDocument

@end

Solution

  • I solved this last week, but figured I'd update to reflect my solution. If you find something better, I would be glad to see it.

    I added a unique property to my class header for starts:

    @property (nonatomic,retain,readonly) NSManagedObjectModel *myManagedObjectModel;
    

    Then added the following to my class implementation:

    -(NSManagedObjectModel*)myManagedObjectModel {
        if (myManagedObjectModel)
            return myManagedObjectModel;
    
        NSBundle *bundle = [NSBundle mainBundle];
        NSString *modelPath = [bundle pathForResource:kDataManagerModelName ofType:@"momd"];
        myManagedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:[NSURL fileURLWithPath:modelPath]];
    
        return myManagedObjectModel;
    }
    
    -(NSManagedObjectModel*)managedObjectModel {
        return self.myManagedObjectModel;
    }
    

    Since I can override the get property for the managedObjectModel, this works out fairly well. The UIManagedDocument initializes and works fine in my tests and implementations so far. Doing a trace shows the managedObjectModel gets called on init, so I'm assuming everything is initialized correctly from the returned result.