2017-07-31 29 views
7

我正在構建一個嚴重依賴CloudKit進行數據同步的應用程序。每次啓動應用程序時,它都會使用CKFetchNotificationChangesOperation來查找服務器上所做的所有更改。這成功返回所有已創建和/或修改的對象,但我現在處於我也希望我的應用程序基於這些消息刪除記錄的階段。CloudKit:根據CKQueryNotification刪除本地對象

在我的應用程序中,我存儲在CoreData中的每個對象還包含該對象的在線表示的recordID。這樣我可以輕鬆地拾取需要修改的對象。

刪除對象似乎很難,因爲CloudKit只會返回這些對象的recordID,並且不會提供可用於在CoreData數據庫中查找我要查找的對象的recordType。

問題

一個人如何正確處理與多個記錄類型的情況下CloudKit「刪除」通知?

+1

您是否生成'recordID'或者它是CloudKit爲您生成的? CloudKit是否真的不給你任何有關被刪除的CK記錄類型的信息? –

+1

我不確定我遵循:您有多種記錄類型的通知,並且您希望在收到notif時刪除記錄?或者,您收到關於已刪除記錄的通知,並且您正試圖瞭解被刪除的內容? – Thunk

+0

感謝您的回覆! @TomHarrington CloudKit生成recordID,我將它們保存在本地以供識別。 Thunk,當記錄被刪除時,我收到notifs,並且我希望能夠根據該notif刪除該對象的本地版本。你們中的任何一個人都會知道嗎? – Joris416

回答

3

如果CloudKit沒有給出任何有關被刪除記錄類型的指示,那麼處理這件事很痛苦。您不能在不知道實體類型的情況下刪除核心數據中的對象,因此如果CloudKit不能提供任何線索,則需要檢查每個可能具有recordId的實體。

刪除過程與通常的核心數據相同。使用`recordId =%@'之類的謂詞來執行提取請求以找到匹配對象,如果找到一個請刪除它,除非必須爲每個潛在實體重複此操作。幫助是將recordId存儲在一個新的獨立的實體中,創建一個名爲東西的新實體,例如CKRecordInfo,並將recordId保留在那裏,每個具有CloudKit信息的實體都將與此實體具有一對一的關係。設置你將獲取新的CKRecordInfo實體的實例,並刪除與其相關的任何對象。

同時,雖然 - 我沒有使用過CloudKit,但它有點令人驚訝給你只是recordId沒有關於記錄類型的信息。如果可能,從通知獲取信息將是理想的。

+0

我想這是現​​在可用的選項的最確鑿的答案,但我發現它真的很笨拙,蘋果不會給recordType刪除記錄。我試圖將recordType字段添加到首選的recordFields,但是它只是返回一個錯誤,指出它找不到該字段。另一種關係意味着我必須爲每個通知執行另一個獲取請求,而且這樣做效率不高,所以我只是遍歷所有recordTypes,直到我找到合適的一個。謝謝! – Joris416

3

根據您在評論中的說明,我建議您在創建訂閱時配置.recordFields字典。您可以在此字典中傳遞有限數量的信息,例如記錄類型。當您收到刪除通知時,您可以從通知對象中解壓記錄字段。

您可以在https://developer.apple.com/documentation/cloudkit/ckquerynotification/1428114-recordfields

更新

發現在蘋果的文檔更多信息下面是如何做到這一點。我使用Objective-C,因此您必須理清SWIFT語法。但步驟是:

創建一組記錄我要在通知符

創建訂閱

發送創建NotificationInfo對象,

加入我的期望按鍵陣列到NotificationInfo對象,

使用a創建子設備CKModifySubscriptionsOperation

NSArray *desiredKeys = @[fieldname1, fieldname1, fieldname1]; 
CKQuerySubscription *subscription = [[CKQuerySubscription alloc] initWithRecordType:recordName 
                      predicate:searchConditions 
                    subscriptionID:subscriptionID 
                      options:fireOn]; 

CKNotificationInfo *notificationInfo = [CKNotificationInfo new]; 
notificationInfo.shouldBadge = shouldBadge; 
notificationInfo.desiredKeys = desiredKeys; 

subscription.notificationInfo = notificationInfo; 

CKModifySubscriptionsOperation *subOp = [[CKModifySubscriptionsOperation alloc] initWithSubscriptionsToSave:subsToCreate subscriptionIDsToDelete:subsToDelete]; 
subOp.modifySubscriptionsCompletionBlock = ^(NSArray<CKSubscription *> *savedSubscriptions, 
              NSArray<NSString *> *deletedSubscriptionIDs, 
              NSError *operationError) 
{ 
    //do whatever 
} 

subOp.database = database;  //set to either public or private DB 
[myQueue addOperation:subOp]; 

當你收到通知,你剛纔拉的對象背出notificationInfo的:

NSString *value1 = [queryNotification.recordFields objectForKey:fieldname1]; 

如果不會讓你真正添加RECORDTYPE,那麼你可能需要創建一個自定義字段與一些記錄類型的指示符,然後如上所述傳遞它,或者使用通知中收到的recordID獲取有問題的記錄。

+0

嗨!抱歉,遲到的答覆..我試圖實現你的解決方案,真的給了我希望,但iCloud給了我一個錯誤,說它無法找到字段'recordType'。蘋果的文檔似乎沒有提供我應該輸入的密鑰,所以你有什麼想法是正確的關鍵? – Joris416

相關問題