Maj*_*eli 1 core-data ipad ios
我正在为我的应用程序实现备份/恢复功能,但在从备份恢复sqlite文件并尝试访问某些数据后,我收到此错误:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Object's persistent store is not reachable from this NSManagedObjectContext's coordinator'
Run Code Online (Sandbox Code Playgroud)
回到ARC之前,您可以在appdelegate上找出核心数据对象,然后在您尝试访问ManagedObjectContext时重建它们.你现在怎么做?
编辑:
那时我一定是做错了.我可以将托管对象上下文设置为不只读,但是当我尝试访问数据时,我得到了相同的错误.有什么建议?
- (void)restoreDatabase {
ICAMAppDelegate *appDelegate = (ICAMAppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.managedObjectContext = nil;
NSError *error;
// Delete Persistent Store
NSArray *stores = [[appDelegate persistentStoreCoordinator] persistentStores];
NSPersistentStore *store = [stores objectAtIndex:0];
NSURL *storeURL = store.URL;
[[appDelegate persistentStoreCoordinator] removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtPath:storeURL.path error:&error];
NSString * databaseName = @"ICAMMobile.sqlite";
NSString * databaseBackupName = @"ICAMMobile.sqlite.bak";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSString *backupPath = [documentsDir stringByAppendingPathComponent:databaseBackupName];
NSString *dbPath = [documentsDir stringByAppendingPathComponent:databaseName];
if([fileManager fileExistsAtPath:backupPath])
{
if (![fileManager copyItemAtPath:backupPath toPath:dbPath error:&error])
{
NSLog(@"Failed to create writable database file with message '%@'.", [error localizedDescription]);
}
else
{
[appDelegate.managedObjectContext reset];
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是有效的.我需要[appDelegate persistentStoreCoordinator] addPersistentStoreWithType在替换文件后调用.
编辑: 作为奖励我也添加了我的备份数据库方法.
- (void)restoreDatabase {
ICAMAppDelegate *appDelegate = (ICAMAppDelegate *)[[UIApplication sharedApplication] delegate];
NSError *error;
// Delete Persistent Store
NSArray *stores = [[appDelegate persistentStoreCoordinator] persistentStores];
NSPersistentStore *store = [stores objectAtIndex:0];
NSURL *storeURL = store.URL;
[[appDelegate persistentStoreCoordinator] removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtPath:storeURL.path error:&error];
NSString * databaseName = @"ICAMMobile.sqlite";
NSString * databaseBackupName = @"ICAMMobile.sqlite.bak";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSString *backupPath = [documentsDir stringByAppendingPathComponent:databaseBackupName];
NSString *dbPath = [documentsDir stringByAppendingPathComponent:databaseName];
if([fileManager fileExistsAtPath:backupPath])
{
if (![fileManager copyItemAtPath:backupPath toPath:dbPath error:&error])
{
NSLog(@"Failed to create writable database file with message '%@'.", [error localizedDescription]);
}
else
{
[[appDelegate persistentStoreCoordinator] addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error];
}
}
}
- (void)backupDatabase {
NSString * databaseName = @"ICAMMobile.sqlite";
NSString * databaseBackupName = @"ICAMMobile.sqlite.bak";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSString *backupPath = [documentsDir stringByAppendingPathComponent:databaseBackupName];
NSString *dbPath = [documentsDir stringByAppendingPathComponent:databaseName];
NSURL *toURL = [NSURL fileURLWithPath:backupPath];
if([fileManager fileExistsAtPath:backupPath])
{
//get rid of the old copy, only one allowed
[fileManager removeItemAtPath:backupPath error:&error];
}
if([fileManager fileExistsAtPath:dbPath])
{
if ([fileManager copyItemAtPath:dbPath toPath:backupPath error:&error]) {
[toURL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
} else {
NSLog(@"Failed to create writable database file with message '%@'.", [error localizedDescription]);
}
}
}
Run Code Online (Sandbox Code Playgroud)