我遇到了这方面的问题,现在阅读几本教程以及一本书中的例子,但是这些书更多地提出了一个对我来说太复杂的深层复制。这个iCloud的东西无论如何令人困惑。我是否正确地做到了这一点:
用户在应用中启用iCloud: - 尝试将本地商店复制到icloud - 删除本地商店
用户在应用中停用iCloud: - 尝试将商店复制到本地 - 删除无处不在的内容 - 删除icloud的本地副本
我错过了什么吗?
额外问题:我如何在复制过程中“阻止”应用程序?我应该在哪里放置此“阻止”代码?
这将是我的代码:
- (bool)moveStoreToICloud {
NSLog(<#NSString * _Nonnull format, ...#>)(@" called");
return [self moveStoreFileToICloud:self.store delete:YES backup:YES];
}
- (bool)moveStoreFileToICloud:(NSURL*)fileURL delete:(bool)shouldDelete backup:(bool)shouldBackup {
NSLog(@" called");
// Always make a backup of the local store before migrating to iCloud
if (shouldBackup)
[self backupLocalStore];
NSPersistentStoreCoordinator *migrationPSC = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.model];
// Open the existing local store using the original options
NSDictionary *options =
@{
NSMigratePersistentStoresAutomaticallyOption:@YES
,NSInferMappingModelAutomaticallyOption:@YES
,NSPersistentStoreUbiquitousContentNameKey:ubiquitousContentNameKey
//,NSPersistentStoreUbiquitousContentURLKey:@"ChangeLogs" // Optional since iOS7
};
id sourceStore = [migrationPSC addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:fileURL options:options error:nil];
if (!sourceStore) {
NSLog(@" failed to add old store");
return FALSE;
} else {
NSLog(@" Successfully added store to migrate");
bool moveSuccess = NO;
NSError *error;
NSLog(@" About to migrate the store...");
// Now migrate the store using the iCloud options
id migrationSuccess = [migrationPSC migratePersistentStore:sourceStore toURL:[_iCloudStore URL] options:options withType:NSSQLiteStoreType error:&error];
if (migrationSuccess) {
moveSuccess = YES;
NSLog(@"store successfully migrated");
// Now delete the local file
if (shouldDelete) {
NSLog(@" deleting local store");
[self destroyAllLocalDataForThisApplication];
} else {
NSLog(@" not deleting local store");
}
[self resetCoreData];
[self setupCoreData];
[[NSNotificationCenter defaultCenter] postNotificationName:@"SomethingChanged"
object:nil];
return TRUE;
}
else {
NSLog(@"Failed to migrate store: %@, %@", error, error.userInfo);
return FALSE;
}
}
return FALSE;
}
/*! Moves an iCloud store to local by migrating the iCloud store to a new local store and then removes the store from iCloud.
Note that even if it fails to remove the iCloud files it deletes the local copy. User may need to clean up orphaned iCloud files using a Mac!
@return Returns YES of file was migrated or NO if not.
*/
- (bool)moveStoreToLocal {
NSLog(@"moveStoreToLocal called");
// Lets use the existing PSC
NSPersistentStoreCoordinator *migrationPSC = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.model];
// Open the store
NSDictionary *options =
@{
NSMigratePersistentStoresAutomaticallyOption:@YES
,NSInferMappingModelAutomaticallyOption:@YES
,NSPersistentStoreUbiquitousContentNameKey:ubiquitousContentNameKey
//,NSPersistentStoreUbiquitousContentURLKey:@"ChangeLogs" // Optional since iOS7
};
id sourceStore = [migrationPSC addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[_iCloudStore URL] options:options error:nil];
if (!sourceStore) {
NSLog(@" failed to add old store");
return FALSE;
} else {
NSLog(@" Successfully added store to migrate");
bool moveSuccess = NO;
NSError *error;
NSLog(@" About to migrate the store...");
id migrationSuccess = [migrationPSC migratePersistentStore:sourceStore toURL:[_store URL] options:options withType:NSSQLiteStoreType error:&error];
if (migrationSuccess) {
moveSuccess = YES;
NSLog(@"store successfully migrated");
// Now delete the local file
[self destroyAlliCloudDataForThisApplication];
[self resetCoreData];
[self setupCoreData];
[[NSNotificationCenter defaultCenter] postNotificationName:@"SomethingChanged"
object:nil];
return TRUE;
}
else {
NSLog(@"Failed to migrate store: %@, %@", error, error.userInfo);
return FALSE;
}
}
return TRUE;
}
#pragma mark - ICLOUD RESET
- (void)destroyAllLocalDataForThisApplication {
if (![[NSFileManager defaultManager] fileExistsAtPath:[[_store URL] path]]) {
NSLog(@"Skipped destroying content, _store.URL is %@",[[_store URL] path]);
return;
}
NSLog(@"\n\n\n\n\n **** Destroying ALL local content for this application, this could take a while... **** \n\n\n\n\n\n");
[self removeAllStoresFromCoordinator:_coordinator];
[self removeAllStoresFromCoordinator:_seedCoordinator];
_coordinator = nil;
_seedCoordinator = nil;
NSError *error;
if([[NSFileManager defaultManager] removeItemAtURL:_storeURL error:&error]){
NSLog(@"Local store successfully removed");
} else {
NSLog(@"\n\n **** FAILED to destroy this application's iCloud content at URL (%@) **** \n%@\n",[_store URL],error);
}
}
- (void)destroyAlliCloudDataForThisApplication {
if (![[NSFileManager defaultManager] fileExistsAtPath:[[_iCloudStore URL] path]]) {
NSLog(@"Skipped destroying iCloud content, _iCloudStore.URL is %@",[[_iCloudStore URL] path]);
return;
}
NSLog(@"\n\n\n\n\n **** Destroying ALL iCloud content for this application, this could take a while... **** \n\n\n\n\n\n");
[self removeAllStoresFromCoordinator:_coordinator];
[self removeAllStoresFromCoordinator:_seedCoordinator];
_coordinator = nil;
_seedCoordinator = nil;
NSDictionary *options =
@{
NSPersistentStoreUbiquitousContentNameKey:ubiquitousContentNameKey
//,NSPersistentStoreUbiquitousContentURLKey:@"ChangeLogs" // Optional since iOS7
};
NSError *error;
if ([NSPersistentStoreCoordinator removeUbiquitousContentAndPersistentStoreAtURL:[_iCloudStore URL]
options:options
error:&error]) {
NSLog(@"\n\n\n\n\n");
NSLog(@"* This application's iCloud content has been destroyed *");
NSLog(@"* On ALL devices, please delete any reference to this application in *");
NSLog(@"* Settings > iCloud > Storage & Backup > Manage Storage > Show All *");
NSLog(@"\n\n\n\n\n");
[[NSFileManager defaultManager] removeItemAtURL:[_iCloudStore URL] error:&error]
} else {
NSLog(@"\n\n **** FAILED to destroy this application's iCloud content at URL (%@) **** \n%@\n",[_iCloudStore URL],error);
}
}
答案 0 :(得分:0)
如果这是一款新应用,请重新考虑您的方法。使用CloudKit,Azure或Firebase。
iCloud Core Data从未可靠地运作。值得庆幸的是Apple现在意识到这一点。从iOS 10 / macOS 12.12开始,NSPersistentStoreUbiquitousContentNameKey
被标记为已弃用,其他iCloud核心数据符号也是如此。