如果用户在设置 - >>下从iCloud支持切换到关闭iCloud支持,是否可以拦截? iCloud - > 文件&数据
显然,当他这样做时,应用程序已经重新启动并进入后台。我的目标是iOS7,我希望与UIManagedDocument
保持同步,否则就像拥有两个不同的UIDocuments:一个支持iCloud,所有数据都创建,直到从开启切换到关闭,另一个没有其中的任何数据。如果我在iCloud支持切换为关闭时创建数据,然后我切换回打开,我得到了支持切换到关闭时的相同数据库。
注意 :我相信nelico的回答是正确的。他写道:“如果您的应用程序正在运行且用户更改通过设置应用程序启用或禁用文档和数据iCloud同步,您的应用程序将收到SIGKILL信号。”
当用户更改设置时,应用程序在后台处于ALREADY状态并收到SIGKILL信号。这是我不明白的,我不想要的。注册NSUbiquityIdentityDidChangeNotification
无法解决此问题。
答案 0 :(得分:2)
另一个更清洁的解决方案是收听NSUbiquityIdentityDidChangeNotification
通知,当您收到该通知时,请检查URLForUbiquityContainerIdentifier
如果它为空,则表示已退出或关闭“文档和数据”。您还应该跟踪当前的普遍性令牌,以便您不仅可以知道他们是否已注销,而且还知道他们是否更改了iCloud帐户。这种情况不止一个人会想到,因为Apple Geniuses喜欢在用户设备出现问题时创建一个新的iCloud帐户。
例如:
id <NSObject,NSCopying,NSCoding> _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...
}
}
答案 1 :(得分:1)
通常你会把检查放在下面的方法中。这样,只要应用程序变为活动状态(包括首次启动),您就可以在将控制权返回给用户之前检查设置,无需在后台进行轮询。对于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];
答案 2 :(得分:0)
无法拦截更改,但您可以通过编程方式检查是否已启用iCloud:
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *ubiquityContainerURL = [fileManager URLForUbiquityContainerIdentifier:nil];
if (!ubiquityContainerURL) {
// iCloud is not enabled
}
当您的应用进入后台时,您可以定期对此进行轮询并让您的应用响应状态的任何变化。
编辑:如果您的应用正在运行且用户更改启用或禁用了文档&amp;通过设置应用程序同步数据iCloud,您的应用程序将收到SIGKILL信号。但是,操作系统可以出于多种原因终止您的应用程序,因此陷阱SIGKILL不是拦截iCloud同步设置更改的可靠方法。你最好定期轮询。