2012-08-13 86 views
3

我想使用iCloud來存儲我的應用程序的userSetting,這裏是我的保存&加載代碼:,它通常做的很好,但有時會崩潰的消息,如:嘗試打開或恢復文檔已經在飛行發送到dealloc實例所以我添加fileState日誌befere openWithCompletionHandler它始終顯示狀態= UIDocumentStateClosed無論將崩潰或不,我保存數據時applecationDidEnterBackground和加載時,applicationDidBecomeActive。iCloud保存數據隨着UIDocument崩潰

節省:

-(void)storeToiCloud{ 
    NSURL *baseURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; 
    if (baseURL) { 
     NSURL *documentsURL = [baseURL URLByAppendingPathComponent:@"Documents"]; 
     NSURL *documentURL = [documentsURL URLByAppendingPathComponent:[NSString stringWithFormat:@"userSetting"]]; 
     if (!loadDocument) { 
      self.loadDocument = [[MyUserDefaultsDocument alloc] initWithFileURL:documentURL]; 
     } 
     loadDocument.myUserDefault = [MyUserDefaults standardUserDefaults]; 

     [loadDocument saveToURL:documentURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) { 
     }]; 
    } 
} 

負荷:在接近連續兩次方法:

-(BOOL)shouldSynciCloud{ 
    if (![Utility iCloudEnable]) { 
     return NO; 
    } 
    NSURL *baseURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; 
    if (baseURL) { 
     self.query = [[[NSMetadataQuery alloc] init] autorelease]; 
     [self.query setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]]; 
     NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == 'userSetting'", NSMetadataItemFSNameKey]; 
     [self.query setPredicate:predicate]; 

     NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 
     [nc addObserver:self selector:@selector(queryDidFinish:) name:NSMetadataQueryDidFinishGatheringNotification object:self.query]; 

     [self.query startQuery]; 
     [Utility showSpinner]; 
     return YES; 
    } 
    return NO; 
} 

- (void)queryDidFinish:(NSNotification *)notification { 
    NSMetadataQuery *query = [notification object]; 

    // Stop Updates 
    [query disableUpdates]; 
    // Stop Query 
    [query stopQuery]; 
    [query.results enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 

     NSURL *documentURL = [(NSMetadataItem *)obj valueForAttribute:NSMetadataItemURLKey]; 

     if([[documentURL lastPathComponent] hasPrefix:@"userSetting"]){ 
      self.document = [[MyUserDefaultsDocument alloc] initWithFileURL:documentURL]; 
      NSString* message; 
      if (document.documentState == UIDocumentStateNormal){ 
       message = @"UIDocumentStateNormal"; 
      }else if (document.documentState == UIDocumentStateClosed) { 
       message = @"UIDocumentStateClosed"; 
      }else if(document.documentState == UIDocumentStateEditingDisabled){ 
       message = @"UIDocumentStateEditingDisabled"; 
      }else if(document.documentState == UIDocumentStateInConflict){ 
       message = @"UIDocumentStateInConflict"; 
      }else if(document.documentState == UIDocumentStateSavingError){ 
       message = @"UIDocumentStateSavingError"; 
      } 
      NSLog(@"state = %@",message); 
      [document openWithCompletionHandler:^(BOOL success) { 
       if (success) { 
        MyUserDefaults *prefs = [MyUserDefaults standardUserDefaults];      
        NSData *book =[document.myUserDefault.realDict objectForKey:@"realbook"]; 
        NSData *readSetting = [document.myUserDefault.realDict objectForKey:@"epubRS"]; 

        if (book&&[[NSUserDefaults standardUserDefaults] boolForKey:@"iCloudBook"]) { 
         [prefs setObject:book forKey:@"realbook"]; 
         [Utility reloadRealBooks]; 
        } 
        if (readSetting&&[[NSUserDefaults standardUserDefaults] boolForKey:@"iCloudSetting"]) { 
         [prefs setObject:readSetting forKey:@"epubRS"]; 
         [Utility setEpubReadSettingFromData:readSetting]; 
        } 
        [prefs save]; 

        [[NSNotificationCenter defaultCenter]postNotificationName:@"iCloudSynced" object:nil]; 
        [Utility removeSpinner]; 
       } 
       else{ 
        [[NSNotificationCenter defaultCenter]postNotificationName:@"iCloudSyncfailed" object:nil]; 
        [Utility removeSpinner]; 
       } 
      }]; 
     } 
    }]; 
    if ([query.results count]==0) { 
     [[NSNotificationCenter defaultCenter]postNotificationName:@"iCloudSyncfailed" object:nil]; 
     [Utility removeSpinner]; 
    } 
    [[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:nil]; 
} 

回答

1

正如this question提到的,如果您的應用程序試圖調用[文件openWithCompletionHandler]時出現錯誤。

因爲openWithCompletionHandler:異步打開文檔,當再次調用該方法時文檔可能仍然打開。

如果發生這種情況,您的應用程序最終會嘗試打開文檔兩次(因爲文檔狀態將保持UIDocumentStateClosed直到完成),這會導致異常被拋出。

+0

我已經解決了通過改變我的代碼這個問題,但是當我寫 [loadDocument saveToURL:documentURL forSaveOperation:UIDocumentSaveForCreating completionHandler:無] 在applicationDidEnterBackground,我的文件無法同步,有時到iCloud – 2012-09-14 05:24:28