【发布时间】:2019-12-30 06:11:02
【问题描述】:
我正在寻求有关以有限方式使用 iCloud 的建议。这些文档专注于多个设备之间的同步,我不需要。当我说 iCloud 时,我还包括 iCloud Drive,如果这很重要的话。
我的 iPhone 应用程序将其数据和状态存储在单个 SQLite 数据库文件中,我想将其保存到 iCloud(或 iCloud Drive)以进行备份,而不是用于在多个设备之间同步更改。在启动时,SQLite 打开数据库文件并同步使用它(我使用的是 FMDB)。数据库文件应该保留在设备上,因此,如果 iCloud 关闭,SQLite 不会知道或关心。 iCloud 会有一个影子副本。
iCloud 副本并不总是需要是最新的——我可以通过编程方式启动 iCloud 更新,并在必要时进行恢复。如果本地数据库文件损坏或用户删除应用程序,我会从 iCloud 恢复文件。该文件通常小于 1 MB,但可能很大 (100 MB),但大多是不变的。
由于共享整个 SQLite 文件存在数据完整性风险,我没有进行同步,而且我无法转换为 Core Data(这是一个使用 FMDB 的大型应用程序)。
我知道 iOS 每天都会对 iCloud 进行备份,如果我可以只从 iCloud(而不是整个设备)恢复我的应用程序就足够了。
我需要有关使用 iCloud 进行影子备份和恢复但不同步的建议。
更新:我在这个问题上取得了进展;我可以在 iCloud 中保存和恢复我的真实 SQLite 文件。我用这两个覆盖子类化了UIDocument:
@implementation MyDocument
// Override this method to return the document data to be saved.
- (id)contentsForType:(NSString *)typeName error:(NSError * _Nullable *)outError
{
NSString *databasePath = ... // path to my SQLite file in Documents;
NSData *dbData = [NSData dataWithContentsOfFile: databasePath];
return dbData; // the entire database file
}
// Override this method to load the document data into the app’s data model.
- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError * _Nullable *)outError
{
NSString *databasePath = ... // path to my SQLite file in Documents;
NSData *dbData = contents;
BOOL ret = [dbData writeToFile: databasePath atomically:YES];
return YES;
}
@end
我的 SQLite 数据库文件在 Documents 中并且它保留在那里,但我因此将卷影副本写入 iCloud:
- (void)sendToICloud
{
NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
NSString *iCloudFileName = @"..."; // a file name I choose
NSURL *ubiquitousPackage = [[ubiq URLByAppendingPathComponent:@"Documents"]
URLByAppendingPathComponent:iCloudFileName];
MyDocument *myDoc = [[MyDocument alloc] initWithFileURL:ubiquitousPackage];
[myDoc saveToURL:[myDoc fileURL] forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
if ( success ) {
[myDoc closeWithCompletionHandler:^(BOOL success) {
}];
} else {
NSLog(@"iCloud write Syncing FAILED with iCloud");
}
}];
}
现在我的问题是:
我在 Xcode 中创建了一个自定义容器,该容器显示在我的权利文件和应用 ID 的开发门户中。我可以从我的两个设备(iPhone 和 iPad)中的任何一个将文档保存到 iCloud。但是,我的两台设备看不到对方的文件。有很多关于这个的随机解决方案的旧线程,但没有解决这个问题。
-
iCloud 文档说文件是增量更新的,但我不知道这是否适用于我的情况。如果我为
MyDocument(我的iCloudFileName,上面)使用一个新文件名,我意识到一个全新的文件将被发送到iCloud。但是,如果我重用以前的文件名并每次发送更新的 NSData(就像我在loadFromContents:ofType:error:中所做的那样),iOS 是否只会发送自上次保存文件以来发生更改的部分?
【问题讨论】:
-
我添加了 Swift 4 的解决方案,如果您还有任何问题,请告诉我,
标签: ios sqlite backup icloud fmdb