ios - 备份 .sqlite(核心数据)

标签 ios objective-c database sqlite core-data

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

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

我在我的应用程序中输入了大约 125 个条目并进行了备份。备份出现在我的保管箱中,但是当我使用 .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];

}

我还从模拟器的文件夹中复制了 .sqlite 文件,并尝试在 .sqlite 浏览器中查看它。它仍然表现出相同的行为。为什么一定会发生这种情况?

最佳答案

从 iOS 7/OS X 10.9 开始,Core Data 默认使用“Write-Ahead Logging”(WAL) 底层 SQLite 存储文件的日志模式。这在

中解释

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

With the WAL mode, Core Data keeps the main store file untouched and appends transactions to a -wal file in the same location. After the Core Data context is saved, the -wal file is not deleted, and the data in that file is not merged to the store file either. Therefore, simply making copies of the store file will likely cause data loss and inconsistency.

这应该可以解释为什么您的 .sqlite 文件本身是不完整的。 作为解决方案,您可以(也在该技术说明中进行了解释):

  • 为 SQLite 存储禁用 WAL 模式(并使用“旧的”回滚日志模式)

    @{NSSQLitePragmasOption:@{@"journal_mode":@"DELETE"}};
    

    添加持久存储时的选项,或者

  • 使用

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

    制作核心数据存储备份副本的方法。

关于ios - 备份 .sqlite(核心数据),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23090637/

相关文章:

ios - 使用变量更改 UIButton 图像

ios - Countly iOS SDK 请求失败

objective-c - 为什么使用 AFNetworking 而不是 dispatch_async?

mysql - 数据库查询 - 按两个值排序(嵌套顺序)

javascript - 在 HTML5 视频元素中播放电影时如何在 IOS 上显示非全尺寸视频?

objective-c - 为 backBarButtonItem 创建自定义标题 View

iphone - CoreData 和 NSInvalidArgumentException 无法识别的选择器发送到实例

android - 解决Android程序与MySQL连接问题的方法

ruby-on-rails - Ruby - 查找具有相同属性的所有记录并将它们分组

ios - 这个字符串是什么格式?