备份.sqlite(核心数据)

时间:2014-04-15 17:33:05

标签: ios objective-c database sqlite core-data

我有一个基于核心数据的应用程序,它使用Dropbox备份和恢复数据。我备份的方式非常简单。我将.sqlite文件复制到用户的保管箱上。

现在我的备份和恢复功能正常。问题出在.sqlite文件本身。看来.sqlite文件不完整

我在我的应用程序中输入了大约125个条目并进行了备份。备份出现在我的Dropbox中,但当我使用.sqlite资源管理器工具查看内容时,我只看到第117个记录的记录。

我尝试更新第一个条目,然后再次观察.sqlite文件,但没有再次更改。

更奇怪的是该应用程序似乎记录了所有更改。当我添加新条目或更新现有条目并重新启动应用程序时,新添加的数据似乎仍然存在。 但是这个新添加的数据不会出现在我的.sqlite文件中。

我正在使用此代码备份:

AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSString *filePath = [[[appDelegate applicationDocumentsDirectory] path] stringByAppendingPathComponent:@"MyApp.sqlite"];


if (account) {
    if ([filesystem isShutDown]) {
        filesystem = [[DBFilesystem alloc] initWithAccount:account];
        [DBFilesystem setSharedFilesystem:filesystem];
    }

    DBPath *newPath = [[DBPath root] childPath:[NSString stringWithFormat:@"Backup - %@.sqlite", [NSDate date]]];
    DBFile *file = [[DBFilesystem sharedFilesystem] createFile:newPath error:nil];
    [file writeContentsOfFile:filePath shouldSteal:NO error:nil];
    [filesystem shutDown];

}

我还从Simulator的文件夹中复制了.sqlite文件,并尝试在.sqlite浏览器中看到它。它仍然表现出相同的行为。有必要发生这种情况的原因吗?

1 个答案:

答案 0 :(得分:6)

从iOS 7 / OS X 10.9开始,核心数据使用"预写日志记录" (WAL)默认 基础SQLite存储文件的日记模式。

中对此进行了解释

Technical Q&A QA1809: New default journaling mode for Core Data SQLite stores in iOS 7 and OS X Mavericks

  

使用WAL模式,Core Data保持主存储文件不受影响   将事务附加到同一位置的-wal文件。之后   保存核心数据上下文,不删除-wal文件和数据   在该文件中也没有合并到商店文件。因此,简单地说   制作商店文件的副本可能会导致数据丢失   不一致性。

这应该解释为什么单独的.sqlite文件不完整。 作为解决方案,你可以(也在技术说明中解释):

  • 通过设置

    为SQLite存储禁用WAL模式(并使用"旧"回滚日记模式)
    @{NSSQLitePragmasOption:@{@"journal_mode":@"DELETE"}};
    
    添加持久存储时的

    选项,或

  • 使用

    - (NSPersistentStore *)migratePersistentStore:(NSPersistentStore *)store toURL:(NSURL *)URL options:(NSDictionary *)options withType:(NSString *)storeType error:(NSError **)error
    

    制作Core Data商店备份副本的方法。