我有一个场景,我的应用程序当前在App Store中没有启用iCloud,但随着我正在进行的更新,iCloud将在那里。用户可以在升级后立即选择是否在使用应用程序时立即使用iCloud,并且还可以决定在应用程序内打开/关闭它。
现在,如果用户在开始时选择“是”以使用iCloud,则数据会从App Store版本(非iCloud)迁移到iCloud,并且我可以将数据从iCloud存储迁移回本地存储。用户在应用程序中关闭iCloud。
然而,逻辑会告诉我,如果我想让用户再次在应用程序中打开iCloud,它应该将本地迁移到iCloud存储。
以下是在App Delegate:
- (void)upgradeAndMigrateCoreDataToiCloud {
NSLog(@"Just upgraded your app. On the next run, this does not happen again.");
NSURL *storeURL = [self.persistentStoreCoordinator.persistentStores.lastObject URL];
NSLog(@"Current Store URL (before migration): %@", [storeURL description]);
NSPersistentStore *currentStore = self.persistentStoreCoordinator.persistentStores.lastObject;
URLByAppendingPathComponent:@"NewStore.sqlite"];
NSURL *cloudURL = [self grabCloudPath:@"CloudLogs"];
NSString *cloudStoreTitle = @"EnvyCloud";
NSDictionary *options = @{NSPersistentStoreUbiquitousContentURLKey: cloudURL,
NSPersistentStoreUbiquitousContentNameKey: cloudStoreTitle, NSMigratePersistentStoresAutomaticallyOption : @YES,
NSInferMappingModelAutomaticallyOption : @YES};
[self.persistentStoreCoordinator migratePersistentStore:currentStore toURL:storeURL options:options withType:NSSQLiteStoreType error:nil];
storeURL = [self.persistentStoreCoordinator.persistentStores.lastObject URL];
NSLog(@"Current Store URL (after migration): %@", [storeURL description]);
}
完美无缺。
以下是用户想要从设置中启用iCloud同步的代码(如果之前关闭的话,或者如果用户将其关闭并且现在想要将其重新打开):
- (void)iCloudHasBeenEnabledFromSettings
{
NSURL *iCloud = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier: nil];
if ((iCloud) && ([[NSUserDefaults standardUserDefaults] boolForKey:@"iCloudOn"]))
{
NSLog(@"iCloud is enabled, and so we can do the migration from the local to iCloud");
[self iCloudNotifications];
NSURL *storeURL = [self.persistentStoreCoordinator.persistentStores.lastObject URL];
NSLog(@"Current Store URL (before migration from local to iCloud): %@", [storeURL description]);
NSPersistentStore *currentStore = self.persistentStoreCoordinator.persistentStores.lastObject;
NSURL *cloudURL = [self grabCloudPath:@"CloudLogs"];
NSString *cloudStoreTitle = @"EnvyCloud";
NSDictionary *options = @{NSPersistentStoreUbiquitousContentURLKey: cloudURL,
NSPersistentStoreUbiquitousContentNameKey: cloudStoreTitle, NSMigratePersistentStoresAutomaticallyOption : @YES,
NSInferMappingModelAutomaticallyOption : @YES};
[self.persistentStoreCoordinator migratePersistentStore:currentStore toURL:storeURL options:options withType:NSSQLiteStoreType error:nil];
storeURL = [self.persistentStoreCoordinator.persistentStores.lastObject URL];
NSLog(@"Current Store URL (after migration from local to iCloud): %@", [storeURL description]);
}
else if (!(iCloud) && ([[NSUserDefaults standardUserDefaults] boolForKey:@"iCloudOn"]))
{
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"iCloud is Disabled on the Device" message:@"Do you want to turn it on now? If so, you can do this from the device Settings" delegate:self cancelButtonTitle:@"Turn OFF iCloud" otherButtonTitles:@"Settings", nil];
[alertView show];
}
}
这里唯一的区别是我正在重新调用iCloud通知,并且我有一个if语句来检查设备上是否启用了iCloud。
检查NSLog
路径的最后一个storeURL
是问题所在。
在升级方法中,迁移后的storeURL
为:
Current Store URL (after migration): file:///var/mobile/Applications/B07684DE-F74A-4503-A7B3-CD6D82CD087D/Documents/CoreDataUbiquitySupport/mobile~F6322EC0-DA27-4EEB-A6A4-0D3EA875241B/EnvyCloud/3B2005FA-FEEE-4F90-A049-E068B35F09AA/store/Envylope.sqlite
显示已正确迁移。
在第二种方法中,从本地迁移到iCloud之前的当前存储URL是:
Current Store URL (before migration): file:///var/mobile/Applications/B07684DE-F74A-4503-A7B3-CD6D82CD087D/Documents/Envylope.sqlite
问题
问题是迁移后,NSLog仍然是:
Current Store URL (before migration): file:///var/mobile/Applications/B07684DE-F74A-4503-A7B3-CD6D82CD087D/Documents/Envylope.sqlite
在此方法(iCloudHasBeenEnabledFromSettings
)中,如果我将NSPersistentStoreUbiquitousContentNameKey
更改为略有不同的名称(之前为EnvyCloud
并将其更改为例如EnvyCloudNew
),则它有效,NSLog
向我显示CoreDataUbiquityContainer
。
当然我做错了,或者它是如何工作的,它不能使用“相同的”NSPersistentStoreUbiquitousContentNameKey?
此外,使用其他NSPersistentStoreUbiquitousContentNameKey
?
更新
我一直在做很多工作,对这个问题有一些更新,我真的希望有人可以帮忙。
如果我不更改NSPersistentStoreUbiquitousContentNameKey
的名称并保持不变,并且如果我通过迁移传递错误参数,则控制台中的输出错误为:
Error = Error Domain=NSCocoaErrorDomain Code=134080 "The operation couldn’t be completed. (Cocoa error 134080.)" UserInfo=0x15e9ae90 {NSUnderlyingException=Can't add the same store twice}
这是有意义的,它不能两次添加相同的商店。
我可以通过首先迁移persistentStore,然后在最终添加一个新的persistentStore之前设置_persistentStoreCoordinator = nil
来解决这个问题 - 这是有效的,但同样,这对我来说似乎不对。我需要这样做是没有意义的。如果我选择从本地商店返回到iCloud,为什么我不能从已经存储在iCloud中的内容重建?
我希望此更新有助于指出某人指出我正确的方向。
任何想法都将不胜感激。