我在我的应用程序中使用coredata,并希望提供创建和恢复安全副本的可能性。我的过程相对简单: - 用户只需创建当前活动数据库的副本,这是一个新备份 - 如果他选择恢复备份,则会创建当前活动数据库的安全副本,然后将删除活动数据库,并将复制所选安全副本并将其重命名为先前的活动数据库名称。这有用吗?还是有陷阱?
这是我的代码:
#pragma mark Database methods
- (BOOL)createSafetyCopy: (void (^)(void))completionHandler
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSString *dbPath = [self getFullDBPathAsString];
if([fileManager fileExistsAtPath:dbPath]) {
//Create the timestamp
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"yyyyMMdd"];
NSDateFormatter *timeFormat = [[NSDateFormatter alloc] init];
[timeFormat setDateFormat:@"HHmmss"];
NSDate *now = [[NSDate alloc] init];
NSString *timeStamp = [NSString stringWithFormat:@"%@_%@", [dateFormat stringFromDate:now], [timeFormat stringFromDate:now]];
NSString *copyPath = [[self.applicationDocumentsDirectory URLByAppendingPathComponent:[NSString stringWithFormat:@"%@%@", timeStamp, kSafetyCopySuffix]] path];
bool success = [fileManager copyItemAtPath:dbPath toPath:copyPath error:&error];
if (!success){
NSLog(@"Failed to create safety copy with message '%@'.", [error localizedDescription]);
return FALSE;
} else {
completionHandler();
}
} else {
NSLog(@"Active database doesn't exist at path: %@", dbPath);
return FALSE;
}
return TRUE;
}
- (NSArray *)getListOfSafetyCopies
{
NSFileManager *manager = [NSFileManager defaultManager];
//get the apps documents directory
NSString *documentsDirectory = [self.applicationDocumentsDirectory path];
// grab all the files in the documents dir
NSArray *allFiles = [manager contentsOfDirectoryAtPath:documentsDirectory error:nil];
// filter the array for only safety copies
NSPredicate *filter = [NSPredicate predicateWithFormat:@"self ENDSWITH %@", kSafetyCopySuffix];
NSArray *safetyCopies = [allFiles filteredArrayUsingPredicate:filter];
return safetyCopies;
}
- (BOOL)restoreSafetyCopy:(NSString *)safetyCopyName
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSString *fullSafetyCopyPath = [[self.applicationDocumentsDirectory URLByAppendingPathComponent:safetyCopyName] path];
if([fileManager fileExistsAtPath:fullSafetyCopyPath]){
//create safety copy of currently active database
//[self createSafetyCopy];
//Then delete active database
if ([fileManager removeItemAtPath:[self getFullDBPathAsString] error:&error]){
//And if successfull replace it with the safety copy;
if (![fileManager copyItemAtPath:fullSafetyCopyPath toPath:[self getFullDBPathAsString] error:&error]){
NSLog(@"Failed to restore safety copy with message '%@'.", [error localizedDescription]);
return FALSE;
}
} else {
NSLog(@"Failed to delete active database with message '%@'.", [error localizedDescription]);
return FALSE;
}
} else {
NSLog(@"Safety copy doesn't exist at path: %@", fullSafetyCopyPath);
return FALSE;
}
return TRUE;
}
答案 0 :(得分:0)
CoreData数据不仅存储在单个sql文件中。在我的DB文件夹中,我看到3个文件:Model.sqlite,Model.sqlite-shm,Model.sqlite-wal。
你可以阅读有关WAL-journal的内容,但据我所知,你不能只依赖于复制1个sqlite文件。一些数据(事务)存储在WAL中。
其实你可以在这里阅读: Technical Q&A QA1809