2013-02-06 12 views
1

我正在編寫一個使用核心數據並與iCloud同步的應用程序。要做到這一點,我有一個UIManagedDocument我設置如下圖所示:使用iCloud解決核心數據衝突

UIManagedDocument *document = [[UIManagedDocument alloc] initWithFileURL:[self iCloudStoreURL]]; 
     document.persistentStoreOptions = @{NSPersistentStoreUbiquitousContentNameKey: [document.fileURL lastPathComponent], NSPersistentStoreUbiquitousContentURLKey: [self iCloudCoreDataLogFilesURL], NSMigratePersistentStoresAutomaticallyOption: @YES, NSInferMappingModelAutomaticallyOption : @YES}; 
     self.mydoc = document; 
     [document release]; 

     [document.managedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; 

     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(documentContentsChanged:) name:NSPersistentStoreDidImportUbiquitousContentChangesNotification object:document.managedObjectContext.persistentStoreCoordinator]; 
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(documentStateChanged:) name:UIDocumentStateChangedNotification object:document]; 


     if (![[NSFileManager defaultManager] fileExistsAtPath:[self.mydoc.fileURL path]]) { 
      // does not exist on disk, so create it 
      [self.mydoc saveToURL:self.mydoc.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) { 
       [self populateTable];//synchronous call. few items are added 
       [self iCloudIsReady]; 
      }]; 
     } else if (self.mydoc.documentState == UIDocumentStateClosed) { 
      // exists on disk, but we need to open it 
      [self.mydoc openWithCompletionHandler:^(BOOL success) { 
       [self iCloudIsReady]; 
      }]; 
     } else if (self.mydoc.documentState == UIDocumentStateNormal) { 
      // already open and ready to use 
     } 
    } 

我的這種方法的問題是,我保持兩個設備上運行應用程序時會出現「樂觀鎖失敗」。我在Apple的Core Data文檔中看到,「避免」這種問題的一種方法是將合併策略設置爲NSMergeByPropertyObjectTrumpMergePolicy,這是我已經在做的事情,但由於某種原因無法正常工作。

我無法找到的一件事是如何解決這個問題。例如,如果這是可能發生的事情,我的應用程序應該至少知道並準備好處理這種行爲。但我不知道如何處理這個問題。例如,我如何獲得衝突的對象並解決它們?因爲每次發生這種故障時,我在嘗試保存文檔時都會遇到UIDocumentStateSavingError,並且停止出現此錯誤的唯一方法是通過殺死應用程序並重新啓動它。

+0

爲什麼這是一個問題?您是否看到數據損壞或其他不良行爲? – ImHuntingWabbits

+0

這是一個問題,有兩個原因。其一,兩臺設備之間的數據會有所不同。二,收到故障的設備在關閉應用程序之前無法保存文檔。 – Abras

+0

我還沒有使用'UIManagedDocument',但它有兩個嵌套的託管對象上下文,它的'managedObjectContext'只獲取子上下文。也許你需要在父上下文中設置它? –

回答

0

我終於明白了這一點(至少,我想我是)。顯然,在iOS6 +(我不知道iOS5)UIManagedDocument負責所有合併。所以,下面的觀察者只負責調用「mergeChangesFromContextDidSaveNotification:」實際上是合併了剛剛合併的內容。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(documentContentsChanged:) name:NSPersistentStoreDidImportUbiquitousContentChangesNotification object:document.managedObjectContext.persistentStoreCoordinator]; 

... 

- (void)documentContentsChanged:(NSNotification *)notification { 
     [self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification]; 
} 

呼喚「mergeChangesFromContextDidSaveNotification:」是負責觸發「樂觀鎖失敗」的路線。我刪除它,一切按預期開始工作。不幸的是,這隻持續了幾個小時。現在我不斷收到「iCloud Timed Out」的錯誤,但是這個我確信這是Apple的錯。

無論如何,經過大量的錯誤和三種不同的iCloud + Core Data方法之後,我認爲我會堅持將iCloud整合到我的應用程序中。這太不穩定和越野車。我真的希望蘋果公司能夠用iOS6解決這個問題,但iCloud + Core Data是一個非常強大的工具,不幸的是,它還沒有準備好。

感謝大家誰試圖幫助。