CoreData, automatic migration and sandbox problems.

  • Hi,

    I'm having trouble with automatic migrations and sandbox.

    When the user opens an old file, the automatic migration fails due to no
    write permission to the file.

    -
    (BOOL)configurePersistentStoreCoordinatorForURL:(NSURL*)url
    ofType:(NSString*)fileType modelConfiguration:(NSString*)configuration
    storeOptions:(NSDictionary*)storeOptions error:(NSError**)error

    {

    NSMutableDictionary *options = nil;

    if (storeOptions != nil) {

    options = [storeOptions mutableCopy];

    } else {

    options = [[NSMutableDictionary alloc] init];

    }

    [options setObject:[NSNumber numberWithBool:YES]
    forKey:NSMigratePersistentStoresAutomaticallyOption];

    [options setObject:[NSNumber numberWithBool:YES]
    forKey:NSInferMappingModelAutomaticallyOption];

    *//[options setObject:[NSNumber numberWithBool:YES]
    forKey:NSReadOnlyPersistentStoreOption];*

    BOOL result [super configurePersistentStoreCoordinatorForURL:url ofType:fileType
    modelConfiguration:configuration storeOptions:options

    error:error];

    *//if (*error) {*

    * //      *** Fails here ****

    *// [[NSAlert alertWithError:*error] runModal];*

    *//}*

    [options release];

    return result;

    }

    Just wondering if anyone has a suggestion about how I can avoid writing to
    the file, e.g. forcing the user to re-save or duplicate the document before
    attempting the migration. It works fine for non-sandbox builds.

    Kind regards,
    Samuel
  • If you want to check whether a store needs to be migrated and ask the user, you can use [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:::] to get the metadata for the document in question and [NSManagedObjectModel isConfiguration:compatibleWithStoreMetadata:] to check whether that is compatible with the current MOM.

    A good place to do these checks is in NSDocumentController before attempting to open the doc.

    On 2012-05-28, at 9:59 AM, Samuel Williams wrote:

    > Hi,
    >
    > I'm having trouble with automatic migrations and sandbox.
    >
    > When the user opens an old file, the automatic migration fails due to no
    > write permission to the file.
    >
    > -
    > (BOOL)configurePersistentStoreCoordinatorForURL:(NSURL*)url
    > ofType:(NSString*)fileType modelConfiguration:(NSString*)configuration
    > storeOptions:(NSDictionary*)storeOptions error:(NSError**)error
    >
    > {
    >
    > NSMutableDictionary *options = nil;
    >
    > if (storeOptions != nil) {
    >
    > options = [storeOptions mutableCopy];
    >
    > } else {
    >
    > options = [[NSMutableDictionary alloc] init];
    >
    > }
    >
    >
    > [options setObject:[NSNumber numberWithBool:YES]
    > forKey:NSMigratePersistentStoresAutomaticallyOption];
    >
    > [options setObject:[NSNumber numberWithBool:YES]
    > forKey:NSInferMappingModelAutomaticallyOption];
    >
    > *//[options setObject:[NSNumber numberWithBool:YES]
    > forKey:NSReadOnlyPersistentStoreOption];*
    >
    > BOOL result > [super configurePersistentStoreCoordinatorForURL:url ofType:fileType
    > modelConfiguration:configuration storeOptions:options
    >
    > error:error];
    >
    > *//if (*error) {*
    >
    > * //      *** Fails here ****
    >
    > *// [[NSAlert alertWithError:*error] runModal];*
    >
    > *//}*
    >
    > [options release];
    >
    > return result;
    >
    > }
    >
    >
    > Just wondering if anyone has a suggestion about how I can avoid writing to
    > the file, e.g. forcing the user to re-save or duplicate the document before
    > attempting the migration. It works fine for non-sandbox builds.
    >
    > Kind regards,
    > Samuel
  • Thanks for the info,

    I've spent quite a bit of time looking into how this would work. I found
    that I can override makeDocumentWithContentsOfURL: and friends, but I'm at
    a loss as to how to check whether the document needs to be migrated. I can
    get the store metadata using [*NSPersistentStoreCoordinator*
    metadataForPersistentStoreOfType:nil URL:contentsURL error:error] but I'm
    not sure how to check whether that needs migration or not. How do I get the
    latest model that would be used for the given file type? Seems like I'd
    need to ask NSPersistentDocument but it doesn't provide any obvious methods
    for doing that...

    I was trying to figure out what is the best use-case for migration -
    currently the file is modified without the user being aware of any change.
    This is quite good but it fails in the sandbox since the user's explicit
    permission is required to save the updated data (?). So, pending this, what
    is the appropriate behaviour in the sandbox? Should we pop up a save box
    asking the user to select a new location for the migration?

    There is (as far as I can see) no documentation in Apple's official docs
    about how to handle this situation...

    What would the canonical approach be in this case?

    Kind regards,
    Samuel

    On 29 May 2012 04:01, Dave Fernandes <dave.fernandes...> wrote:

    > If you want to check whether a store needs to be migrated and ask the
    > user, you can use [NSPersistentStoreCoordinator
    > metadataForPersistentStoreOfType:::] to get the metadata for the document
    > in question and [NSManagedObjectModel
    > isConfiguration:compatibleWithStoreMetadata:] to check whether that is
    > compatible with the current MOM.
    >
    > A good place to do these checks is in NSDocumentController before
    > attempting to open the doc.
    >
    > On 2012-05-28, at 9:59 AM, Samuel Williams wrote:
    >
    >> Hi,
    >>
    >> I'm having trouble with automatic migrations and sandbox.
    >>
    >> When the user opens an old file, the automatic migration fails due to no
    >> write permission to the file.
    >>
    >> -
    >> (BOOL)configurePersistentStoreCoordinatorForURL:(NSURL*)url
    >> ofType:(NSString*)fileType modelConfiguration:(NSString*)configuration
    >> storeOptions:(NSDictionary*)storeOptions error:(NSError**)error
    >>
    >> {
    >>
    >> NSMutableDictionary *options = nil;
    >>
    >> if (storeOptions != nil) {
    >>
    >> options = [storeOptions mutableCopy];
    >>
    >> } else {
    >>
    >> options = [[NSMutableDictionary alloc] init];
    >>
    >> }
    >>
    >>
    >> [options setObject:[NSNumber numberWithBool:YES]
    >> forKey:NSMigratePersistentStoresAutomaticallyOption];
    >>
    >> [options setObject:[NSNumber numberWithBool:YES]
    >> forKey:NSInferMappingModelAutomaticallyOption];
    >>
    >> *//[options setObject:[NSNumber numberWithBool:YES]
    >> forKey:NSReadOnlyPersistentStoreOption];*
    >>
    >> BOOL result >> [super configurePersistentStoreCoordinatorForURL:url ofType:fileType
    >> modelConfiguration:configuration storeOptions:options
    >>
    >> error:error];
    >>
    >> *//if (*error) {*
    >>
    >> * //      *** Fails here ****
    >>
    >> *// [[NSAlert alertWithError:*error] runModal];*
    >>
    >> *//}*
    >>
    >> [options release];
    >>
    >> return result;
    >>
    >> }
    >>
    >>
    >> Just wondering if anyone has a suggestion about how I can avoid writing
    > to
    >> the file, e.g. forcing the user to re-save or duplicate the document
    > before
    >> attempting the migration. It works fine for non-sandbox builds.
    >>
    >> Kind regards,
    >> Samuel
    >
    >
  • On 2012-06-05, at 6:10 AM, Samuel Williams wrote:

    > Thanks for the info,
    >
    > I've spent quite a bit of time looking into how this would work. I found that I can override makeDocumentWithContentsOfURL: and friends, but I'm at a loss as to how to check whether the document needs to be migrated. I can get the store metadata using [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:nil URL:contentsURL error:error] but I'm not sure how to check whether that needs migration or not. How do I get the latest model that would be used for the given file type? Seems like I'd need to ask NSPersistentDocument but it doesn't provide any obvious methods for doing that…

    If you have a typical Core Data app with a single managed object model, then you can get the model using:
    model = [NSManagedObjectModel mergedModelFromBundles:nil];

    If you have a different model for each file type, then I believe you must be overriding -[NSPersistentDocument managedObjectModel]. If so, then whatever model you are providing in that method is the one you would compare against.

    Hopefully someone else can answer the sandboxing-specific questions. I have no experience there.

    >
    > I was trying to figure out what is the best use-case for migration - currently the file is modified without the user being aware of any change. This is quite good but it fails in the sandbox since the user's explicit permission is required to save the updated data (?). So, pending this, what is the appropriate behaviour in the sandbox? Should we pop up a save box asking the user to select a new location for the migration?
    >
    > There is (as far as I can see) no documentation in Apple's official docs about how to handle this situation...
    >
    > What would the canonical approach be in this case?
    >
    > Kind regards,
    > Samuel
    >
    > On 29 May 2012 04:01, Dave Fernandes <dave.fernandes...> wrote:
    > If you want to check whether a store needs to be migrated and ask the user, you can use [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:::] to get the metadata for the document in question and [NSManagedObjectModel isConfiguration:compatibleWithStoreMetadata:] to check whether that is compatible with the current MOM.
    >
    > A good place to do these checks is in NSDocumentController before attempting to open the doc.
    >
    > On 2012-05-28, at 9:59 AM, Samuel Williams wrote:
    >
    >> Hi,
    >>
    >> I'm having trouble with automatic migrations and sandbox.
    >>
    >> When the user opens an old file, the automatic migration fails due to no
    >> write permission to the file.
    >>
    >> -
    >> (BOOL)configurePersistentStoreCoordinatorForURL:(NSURL*)url
    >> ofType:(NSString*)fileType modelConfiguration:(NSString*)configuration
    >> storeOptions:(NSDictionary*)storeOptions error:(NSError**)error
    >>
    >> {
    >>
    >> NSMutableDictionary *options = nil;
    >>
    >> if (storeOptions != nil) {
    >>
    >> options = [storeOptions mutableCopy];
    >>
    >> } else {
    >>
    >> options = [[NSMutableDictionary alloc] init];
    >>
    >> }
    >>
    >>
    >> [options setObject:[NSNumber numberWithBool:YES]
    >> forKey:NSMigratePersistentStoresAutomaticallyOption];
    >>
    >> [options setObject:[NSNumber numberWithBool:YES]
    >> forKey:NSInferMappingModelAutomaticallyOption];
    >>
    >> *//[options setObject:[NSNumber numberWithBool:YES]
    >> forKey:NSReadOnlyPersistentStoreOption];*
    >>
    >> BOOL result =
    >> [super configurePersistentStoreCoordinatorForURL:url ofType:fileType
    >> modelConfiguration:configuration storeOptions:options
    >>
    >> error:error];
    >>
    >> *//if (*error) {*
    >>
    >> * //      *** Fails here ****
    >>
    >> *// [[NSAlert alertWithError:*error] runModal];*
    >>
    >> *//}*
    >>
    >> [options release];
    >>
    >> return result;
    >>
    >> }
    >>
    >>
    >> Just wondering if anyone has a suggestion about how I can avoid writing to
    >> the file, e.g. forcing the user to re-save or duplicate the document before
    >> attempting the migration. It works fine for non-sandbox builds.
    >>
    >> Kind regards,
    >> Samuel
    >
    >
previous month may 2012 next month
MTWTFSS
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
Go to today