iOS:核心数据备份 - 有什么需要注意的吗?

时间:2014-09-10 09:14:04

标签: ios objective-c core-data

我在我的应用程序中使用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;
}

1 个答案:

答案 0 :(得分:0)

CoreData数据不仅存储在单个sql文件中。在我的DB文件夹中,我看到3个文件:Model.sqlite,Model.sqlite-shm,Model.sqlite-wal。

你可以阅读有关WAL-journal的内容,但据我所知,你不能只依赖于复制1个sqlite文件。一些数据(事务)存储在WAL中。

其实你可以在这里阅读: Technical Q&A QA1809