我有一个问题接近尾声。
我的工作是基于这样的信念/经验,即多次播种 iCloud 是一个坏主意,如果用户可以做错事,他可能迟早会这样做。
我想做的事:
A. 当用户将应用偏好“启用 iCloud”从“否”更改为“是”时,显示 AlertView 询问(是或否)用户是否希望使用现有的非 iCloud 数据播种云。
B. 确保应用程序仅在 iCloud 帐户上为 iCloud 播种一次,避免在第一次播种完成后放置 AlertView。
我的方法:
按照 Apple 的有关正确使用 NSUbiquitousKeyValueStore 的文档,我在 - (void)application: dFLWOptions 中使用以下方法:
- (void)updateKVStoreItems:(NSNotification*)notification { // Get the list of keys that changed. NSDictionary* userInfo = [notification userInfo]; NSNumber* reasonForChange = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangeReasonKey]; NSInteger reason = -1; // If a reason could not be determined, do not update anything. if (!reasonForChange) return; // Update only for changes from the server. reason = [reasonForChange integerValue]; if ((reason == NSUbiquitousKeyValueStoreServerChange) || (reason == NSUbiquitousKeyValueStoreInitialSyncChange)) { // 0 || 1 // If something is changing externally, get the changes // and update the corresponding keys locally. NSArray* changedKeys = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangedKeysKey]; NSUbiquitousKeyValueStore* store = [NSUbiquitousKeyValueStore defaultStore]; NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults]; // This loop assumes you are using the same key names in both // the user defaults database and the iCloud key-value store for (NSString* key in changedKeys) {//Only one key: @"iCloudSeeded" a BOOL BOOL bValue = [store boolForKey:key]; id value = [store objectForKey:@"iCloudSeeded"]; [userDefaults setObject:value forKey:key]; } }
}
在应用程序顶部附近包含以下代码:dFLWO:
NSUbiquitousKeyValueStore* store = [NSUbiquitousKeyValueStore defaultStore]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateKVStoreItems:) name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification object:store]; // add appDelegate as observer
加载 iCloud Store 后,仅在从未完成播种的情况下使用非 iCloud 数据播种
- (BOOL)loadiCloudStore { if (_iCloudStore) {return YES;} // Don’t load iCloud store if it’s already loaded NSDictionary *options = @{ NSMigratePersistentStoresAutomaticallyOption:@YES ,NSInferMappingModelAutomaticallyOption:@YES ,NSPersistentStoreUbiquitousContentNameKey:@"MainStore" }; NSError *error=nil; _iCloudStore = [_coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self iCloudStoreURL] options:options error:&error]; if (_iCloudStore) { NSUbiquitousKeyValueStore* store = [NSUbiquitousKeyValueStore defaultStore]; BOOL iCloudSeeded = [store boolForKey:@"iCloudSeeded"];//If the key was not found, this method returns NO. if(!iCloudSeeded) // CONTROL IS HERE [self confirmMergeWithiCloud]; // Accept one USER confirmation for seeding in AlertView ONCE world wide return YES; // iCloud store loaded. } NSLog(@"** FAILED to configure the iCloud Store : %@ **", error); return NO; }
播种完成后,请执行以下操作以防止任何重复播种:
if (alertView == self.seedAlertView) { if (buttonIndex == alertView.firstOtherButtonIndex) { [self seediCloud]; NSUbiquitousKeyValueStore* store = [NSUbiquitousKeyValueStore defaultStore]; [store setBool:YES forKey:@"iCloudSeeded"]; // NEVER AGAIN //[store synchronize]; } } }
在上述过程之前,请务必使用以下方法完全重置 iCloud:
[NSPersistentStoreCoordinator removeUbiquitousContentAndPersistentStoreAtURL:[_iCloudStore URL] options:options error:&error])
恕我直言,这是我的问题的一个非常整洁的解决方案,但我无法完成它。
我的问题:
我如何响应上面 updateKVStoreItems: 的第一个通知?这是一个包含错误信息的通知。我说该值为 TRUE,但我从未将其设置为 TRUE。如何为 NSUbiquitousKeyValueStore 中的键设置默认值?
我发现第一个通知是有道理的:NSUbiquitousKeyValueStoreInitialSyncChange 当那个注释进来时,bValue 是 YES。这是我的问题。就好像 iCloud/iOS 假定任何新的 BOOL 为 TRUE。我最初需要将此值设置为 NO,以便我可以继续遵循 Apple Docs 并将 NSUserDefault 设置为 NO。然后稍后在播种完成后,最终设置值: YES 为键:@“iCloudSeed”
我发现我无法从 Apple 中理解以下内容的含义:
NSUbiquitousKeyValueStoreInitialSyncChange Your attempt to write to key-value storage was discarded because an initial download from iCloud has not yet happened. That is, before you can first write key-value data, the system must ensure that your app’s local, on-disk cache matches the truth in iCloud. Initial downloads happen the first time a device is connected to an iCloud account, and when a user switches their primary iCloud account.
我不太明白下面数字 2 的含义,这是我在网上找到的:
NSUbiquitousKeyValueStoreInitialSyncChange – slightly more complicated, only happens under these circumstances: 1. You start the app and call synchronize 2. Before iOS has chance to pull down the latest values from iCloud you make some changes. 3. iOS gets the changes from iCloud.
如果这个问题是 NSUserDefaults 而不是 NSUbiquitousKeyValueStore,我相信我需要去 registerDefaults。
我快到了,请问我该怎么做!感谢阅读,马克