是否可以在设置 – > iCloud – >文档和数据中拦截iCloud开/关?

如果用户在设置 – > iCloud – > 文档和数据下从iCloud支持切换到关闭,是否可以拦截?

显然,当他这样做时,应用程序已经重新启动并进入后台。 我的目标是iOS7,我希望与UIManagedDocument保持同步,否则就像拥有两个不同的UIDocuments:一个支持iCloud,所有数据都创建,直到从开关切换到关闭,一个新的没有任何数据。 如果我在iCloud支持切换为关闭时创建数据,然后我切换回打开,我得到了支持切换到关闭时的相同数据库。

注意 :我相信nelico的回答是正确的。 他写道:“如果您的应用程序正在运行且用户更改通过设置应用程序启用或禁用文档和数据iCloud同步,您的应用程序将收到SIGKILL信号。”

当用户更改设置时,应用程序在后台处于ALREADY状态并接收SIGKILL信号。 这是我不理解的,我不想要的。 注册NSUbiquityIdentityDidChangeNotification并不能解决这个问题。

另一个更清洁的解决方案是监听NSUbiquityIdentityDidChangeNotification通知,当您收到该通知时,检查URLForUbiquityContainerIdentifier如果它为null,则它们要么注销要么关闭’Documents and Data’。 您还应该跟踪当前的普遍性令牌,以便您不仅可以知道他们是否已注销,而且还知道他们是否更改了iCloud帐户。 这种情况不止是人们想到的,因为Apple Geniuses喜欢在用户设备出现问题时创建一个新的iCloud帐户。

例如:

 id  _currentUbiquityIdentityToken; 

 _currentUbiquityIdentityToken = [[NSFileManager defaultManager] ubiquityIdentityToken]; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector (_iCloudAccountAvailabilityChanged:) name: NSUbiquityIdentityDidChangeNotification object: nil]; 

 - (void)_iCloudAccountAvailabilityChanged:(NSNotification*)notif { if (![_currentUbiquityIdentityToken isEqual:[[NSFileManager defaultManager] ubiquityIdentityToken]]) { // Update the current token and rescan for documents. _currentUbiquityIdentityToken = [[NSFileManager defaultManager] ubiquityIdentityToken]; // Do something about the change here... } } 

通常你会把检查放在下面的方法中。 这样,只要应用程序变为活动状态(包括首次启动),您就可以在将控制权返回给用户之前检查设置,无需在后台进行轮询。 对于UIManagedDocument,您可能希望将存储迁移到仅本地副本并删除任何iCloud内容或相反的内容,具体取决于用户输入。

BTW只需在上一个答案中包含检查,以测试全局iCloud设置是否已打开或关闭。 我不这样做,因为如果用户设置了应用程序特定设置,它只需要更改应用程序行为。

 /*! The app is about to enter foreground so use this opportunity to check if the user has changed any settings. They may have changed the iCloud account, logged into or out of iCloud, set Documents & Data to off (same effect as if they logged out of iCloud) or they may have changed the app specific settings. If the settings have been changed then check if iCloud is being turned off and ask the user if they want to save the files locally. Otherwise just copy the files to iCloud (don't ask the user again, they've just turned iCloud on, so they obviously mean it!) @param application The application */ - (void)applicationWillEnterForeground:(UIApplication *)application { //LOG(@"applicationWillEnterForeground called"); // Check if the settings have changed [[NSUserDefaults standardUserDefaults] synchronize]; NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults]; bool userICloudChoice = [userDefaults boolForKey:_cloudPreferenceKey]; // Check against the current in memory setting if (userICloudChoice == useICloudStorage) { // The setting has not been changed so just ignore //LOG(@" iCloud choice has not changed"); } else { // The setting has changed so do something //LOG(@" iCloud choice has been changed!!"); // iCloud has been turned off so ask the user if they want to keep files locally if (!userICloudChoice) { //LOG(@" Ask user if they want to keep iCloud files ?"); if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { _cloudChangedAlert = [[UIAlertView alloc] initWithTitle:@"You're not using iCloud" message:@"What would you like to do with documents currently on this phone?" delegate:self cancelButtonTitle:@"Keep using iCloud" otherButtonTitles:@"Keep on My iPhone", @"Delete from My iPhone", nil]; } else { _cloudChangedAlert = [[UIAlertView alloc] initWithTitle:@"You're not using iCloud" message:@"What would you like to do with documents currently on this phone?" delegate:self cancelButtonTitle:@"Keep using iCloud" otherButtonTitles:@"Keep on My iPad", @"Delete from My iPad", nil]; } [_cloudChangedAlert show]; } else { // iCloud has been turned on so just copy the files across, don't ask the user again... //LOG(@" iCloud turned on so copy any created files across"); [[CloudManager sharedManager] setIsCloudEnabled:YES]; // This does all the work based on the settings passed to it useICloudStorage = YES; } } } 

哦,如果用户使用其他iCloud帐户登录,也会注册此通知。

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkUserICloudPreferenceAndSetupIfNecessary) name:NSUbiquityIdentityDidChangeNotification object:nil]; 

拦截更改是不可能的,但您可以通过编程方式检查是否已启用iCloud:

 NSFileManager *fileManager = [NSFileManager defaultManager]; NSURL *ubiquityContainerURL = [fileManager URLForUbiquityContainerIdentifier:nil]; if (!ubiquityContainerURL) { // iCloud is not enabled } 

当您的应用进入后台时,您可以定期对此进行轮询并让您的应用响应状态的任何变化。

编辑:如果您的应用程序正在运行且用户更改通过设置应用程序启用或禁用文档和数据iCloud同步,您的应用程序将收到SIGKILL信号。 但是,操作系统可以出于多种原因终止您的应用程序,因此陷阱SIGKILL不是拦截iCloud同步设置更改的可靠方法。 你最好定期轮询。