2014-09-01 48 views
0

我在結尾處有一個問題。如何顯示AlertView請求許可在應用程序的iCloud生命週期中僅一次種植iCloud?

我從信仰/經驗中學習iCloud不止一次是一個壞主意,而且如果用戶可以做錯事情,他可能遲早會做。

我想要做什麼:

A.當用戶從NO到YES,顯示AlertView要求更改應用程序優先「啓用的iCloud」(是或否)如果用戶希望的種子與現有的雲非iCloud數據。

B.確保應用程序只在iCloud帳戶上種一次iCloud,一旦種子完成第一次就不要放置AlertView。

我的方法:

  1. 繼蘋果公司的有關正確使用NSUbiquitousKeyValueStore的,我使用的,下面的方法文檔 - (無效)應用: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]; 
         } 
        } 
    

    }

  2. 在應用程序頂部附近包含以下代碼:dFLWO:

    NSUbiquitousKeyValueStore* store = [NSUbiquitousKeyValueStore defaultStore]; 
    [[NSNotificationCenter defaultCenter] addObserver:self 
               selector:@selector(updateKVStoreItems:) 
                 name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification 
                      object:store]; // add appDelegate as observer 
    
  3. 加載的iCloud存儲後,再與非的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; 
    } 
    
  4. 一旦播種完成執行以下操作以防止重複接種:將

    if (alertView == self.seedAlertView) { 
         if (buttonIndex == alertView.firstOtherButtonIndex) { 
          [self seediCloud]; 
          NSUbiquitousKeyValueStore* store = [NSUbiquitousKeyValueStore defaultStore]; 
          [store setBool:YES forKey:@"iCloudSeeded"]; // NEVER AGAIN 
           //[store synchronize]; 
         } 
        } 
    } 
    
  5. 請務必使用上述方法之前得到一個總的iCloud復位:

    [NSPersistentStoreCoordinator 
         removeUbiquitousContentAndPersistentStoreAtURL:[_iCloudStore URL] 
         options:options 
         error:&error]) 
    

    這是一個非常整潔的解決方案,我的問題,恕我直言,但我不能完全完成它。

    我的問題:

    如何在第一通知updateKVStoreItems迴應:以上?這是一個錯誤信息的通知。我說這個值是TRUE,但我從來沒有把它設置爲TRUE。如何爲NSUbiquitousKeyValueStore中的鍵設置默認值?

    我發現第一個通知是有原因的:NSUbiquitousKeyValueStoreInitialSyncChange 當該筆記進入時,bValue爲YES。這是我的問題。就好像,iCloud/iOS假定任何新的BOOL都是TRUE。 我最初需要此值爲NO,以便我可以繼續並遵循Apple Docs並將NSUserDefault設爲 。再後來,當播種完成後,最終設定值:是爲關鍵:@「iCloudSeeded」

    我發現我無法穿透蘋果以下含義:

    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。

    我快到了, 請問我該怎麼做! 感謝您的閱讀,馬克

回答

0

的代碼一直在尋找既

A. NSUbiquitousKeyValueStoreInitialSyncChange and 
    B. NSUbiquitousKeyValueStoreServerChange 

我無法弄清楚如何處理的通知做。我知道看到我不需要做任何事情。我的應用程序只需要讀取和寫入,以解決我在問題標題中列出的問題。

NSUbiquitousKeyValueStore* store = [NSUbiquitousKeyValueStore defaultStore]; 
    BOOL iCloudSeeded = [store boolForKey:@"iCloudSeeded"]; 

該應用程序與設置在NSUbiquitousKeyValueStore值:

該應用程序與獲取的當前值

NSUbiquitousKeyValueStore* store = [NSUbiquitousKeyValueStore defaultStore]; 
    [store setBool:YES forKey:@"iCloudSeeded"]; 

我相信我是在說,下面的正確:書寫時進入記憶。此後不久,數據被系統放入磁盤。 從那裏獲取並投入iCloud,並在同一個iCloud帳戶上提供給運行相同應用的其他設備。在我描述的應用程序中,不需要添加任何觀察者,也不需要做任何其他事情。這也許是NSUbiquitousKeyValueStore的一個「不尋常」使用。

如果你來這裏尋找一種更「常用」的用法,比如說當用戶在textview中輸入內容並且其後 出現在運行相同應用程序的其他設備的視圖上時,請查看我來的簡單演示在對面:

https://github.com/cgreening/CMGCloudSyncTest 

更好地運作(僅監控)通知處理程序如下:

- (void)updateKVStoreItems:(NSNotification*)notification { 
     NSNumber *reason = notification.userInfo[NSUbiquitousKeyValueStoreChangeReasonKey]; 
     if(!reason) return; 
      // get the reason code 
     NSInteger reasonCode = [notification.userInfo[NSUbiquitousKeyValueStoreChangeReasonKey] intValue]; 
     BOOL bValue; 
     NSUbiquitousKeyValueStore *store; 

     switch(reasonCode) { 
      case NSUbiquitousKeyValueStoreServerChange:{ // code 0, monitoring only 
       store = [NSUbiquitousKeyValueStore defaultStore]; 
       bValue = [store boolForKey:@"iCloudSeeded"]; 
       id value = [store objectForKey:@"iCloudSeeded"]; 
       DLog(@"New value for iCloudSeeded=%d\nNo Action need be take.",bValue); 
        // For monitoring set in UserDefaults 
       [[NSUserDefaults standardUserDefaults] setObject:value forKey:@"iCloudSeeded"]; 
       break; 
      } 
      case NSUbiquitousKeyValueStoreAccountChange: {// ignore, log 
       NSLog(@"NSUbiquitousKeyValueStoreAccountChange"); 
       break; 
      } 
      case NSUbiquitousKeyValueStoreInitialSyncChange:{ // ignore, log 
       NSLog(@"NSUbiquitousKeyValueStoreInitialSyncChange"); 
       break; 
      } 
      case NSUbiquitousKeyValueStoreQuotaViolationChange:{ // ignore, log 
       NSLog(@"Run out of space!"); 
       break; 
      } 
     } 
    } 

添加14年9月3日 很抱歉,但我繼續使用BOOL有麻煩,我切換到一個NSString一個d現在 一切都很好。

方法來確保播種ICOUD「合併」按鈕用於最多一次APP期間終身

  1. 使用NSString和KV_STORE不是BOOL。不需要添加觀察者,除了學習

  2. 在常量中。H:

    #define SEEDED_ICLOUD_MSG @"Have Seeded iCloud" 
    #define ICLOUD_SEEDED_KEY @"iCloudSeeded" 
    
  3. 之前調用函數與非的iCloud數據種子的iCloud:

    NSUbiquitousKeyValueStore* kvStore = [NSUbiquitousKeyValueStore defaultStore]; 
    NSString* strMergeDataWithiCloudDone = 
          [kvStore stringForKey:ICLOUD_SEEDED_KEY]; 
    NSComparisonResult *result = [strMergeDataWithiCloudDone compare:SEEDED_ICLOUD_MSG]; 
    if(result != NSOrderedSame) 
        //put up UIAlert asking user if seeding is desired. 
    
  4. 如果用戶選擇是:爲合併後的關鍵設定值完成。

    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { 
        if (alertView == self.seedAlertView) { 
         if (buttonIndex == alertView.firstOtherButtonIndex) { 
          [self seediCloudwithNoniCloudData]; 
          NSUbiquitousKeyValueStore* kvStoretore = [NSUbiquitousKeyValueStore defaultStore]; 
          [store setObject:SEEDED_ICLOUD_MSG forKey:ICLOUD_SEEDED_KEY]; 
         } 
        } 
    } 
    
  5. 此後上的所有設備,對於所有時間,將碼

    NSUbiquitousKeyValueStore * kvStoretore = [NSUbiquitousKeyValueStore defaultStore]; NSString * msg = [kvStore stringForKey:ICLOUD_SEEDED_KEY];

生產:MSG == SEEDED_ICLOUD_MESSAGE