开发者

A method for 'Save As...' in Core Data app

CD's been an enormous learning curve for me and there's still a bit for me to go, but any help on the following could enable me to lift the current weight on my shoulders!

I'm trying to write a method that implements a "Save As.." for the user in my CD app.

So far I've got:

[saveAsPanel beginSheetModalForWindow:window completionHandler:^(NSInteger userResult)
{
if (userResult == NSOKButton) {
    NSPersistentStoreCoordinator *psc = [self persistentStoreCoordinator];
    NSURL *oldURL = [self URLOfInternalStore]; //returns the current store's URL
    NSURL *newURL = [saveAsPanel URL];
    NSError *error = nil;
    NSPersistentStore *oldStore = [psc persistentStoreForURL:oldURL];
    NSPersistentStore *sqLiteStore = [psc migratePersistentStore:oldStore
                                                           toURL:newURL
                                                         options:nil
                                                        withType:NSXMLStoreType
                                                           error:&error];
}
}];

Unfortunately, I just get the error:

Object's persistent store is not reachable from this NSManagedObjectContext's coordinator.

Should I 'remove' and then 'addPersistentStore...' to update it to the new URL? The doc's seem to suggest that all will be handled with in the 'migrate' method.

Thanks in advance!

Edit:

Ok, well, I've come up with my own 'dirty' method. I can imagine that this isn't an approved way of doing things, but there's no error thrown up and the app works as expected at all times (not often I can say that, either!):

        -(IBAction)saveAsAction:(id)sender
    {
        NSSavePanel *saveAsPanel = [NSSavePanel savePanel];
        [saveAsPanel beginSheetModalForWindow:window completionHandler:^(NSInteger userResult)
        {
        if (userResult == NSOKButton) {
            [self saveAction:@"saveAsCalling"];
            NSURL *newURL = [saveAsPanel URL];
            NSError *error = nil;
            [[NSFileManager defaultManager] copyItemAtURL:[NSURL fileURLWithPath:internalStore] toURL:newURL error:&error];
//internalStore is a hard-wired NSString that holds the path to the bundle's database
        }
        }];
    }

    -(IBAction)loadAction:(id)sender
    {
        NSOpenPanel *loadPanel = [NSOpenPanel openPanel];
        [loadPanel beginSheetModalForWindow:window completionHandler:^(NSInteger userResult)
         {
             if (userResult == NSOKButton) {
                 [self saveAction:@"loadCalling"];
                 NSURL *newURL = [loadPanel URL];
                 NSURL *oldURL = [NSURL fileURLWithPath:internalStore];
                 NSError *error = nil;
                 NSPersistentStoreCoordinator *psc = [SELF_MOC persistentStoreCoordinator];
                 [psc removePersistentStore:[[self persistentStoreCoordinator] persistentStoreForURL:oldURL] error:&error];
                 [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:newURL options:nil error:&error];
                 [[NSFileManager defaultManager] removeItemAtURL:oldURL error:&error];
                 [[NSFileManager defaultManager] copyItemAtURL:newURL toURL:oldURL error:&error];
                 [psc removePersistentStore:[[self persistentStoreCoordinator] persistentStoreForURL:newURL] error:&error];
                 [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:oldURL options:nil error:&error];
             }
         }];
    }

The basic reasoning is this: to do a 'SaveAs...' I simply copy out the SQLLite store file in the mainBundle to wherever the user selects and rename it to what they want - as per TechZen's suggestion.

To do a 'Load' then I first removePersistentStore from the bundle's file, add the one that the user's just chosen. Delete the bundle store (which in theory isn't now being used) and then copy the user's choice back into the bundle.开发者_如何学JAVA Finally, the two operations of remove and addPersistentStore are performed to point the app back to it's bundle's file which is now the user's choice.

Hope that makes sense. If anyone has any thoughts on just how unprofessional a methodology this is then please - be kind as I'm fairly new - let me know. I can't find anything that is more elegant.

I know Apple don't like you using removePersistentStore and addPersistentStore but, as I say no errors are reported (in my actual code I scattered NSLog lines throughout to report what error is holding).


You only use a SaveAs... in a document based app. If you use Core Data as your model, you need to use NSPersistentDocument to save your data. It provide the SaveAs... functionality you seek.

Straight Core Data is used for more database-like apps in which the entire app operates from one data set (more or less.)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜