2017-02-10 85 views
2

我取出由CloudKit服務器記錄的變化,但每一次我得到錯誤如何使用previousServerchangetoken初始化CKFetchRecordZoneChangesOperation?

[LogFacilityCK]得到了操作E0367CA861DAF5A9連接錯誤: 錯誤域= NSCocoaErrorDomain代碼= 4097「連接服務命名 com.apple .cloudd」的UserInfo = {NSDebugDescription =連接到服務 命名com.apple.cloudd}

我知道原因,因爲我錯誤地初始化CKFetchRecordZoneChangesOperation 請檢查下面的代碼並糾正我:

CKFetchRecordZoneChangesOperation *operation = [[CKFetchRecordZoneChangesOperation alloc]initWithRecordZoneIDs:@[ recordZoneID ] optionsByRecordZoneID:@{@"Zone":recordZoneID,@"FetchRecordZoneChangesOptions":option}]; 

我需要這部分幫助:

**@{@"Zone":recordZoneID,@"FetchRecordZoneChangesOptions":option}];** 

回答

3

只需創建變量:

var serverChangeToken: CKServerChangeToken? { 

    guard let encoded = UserDefaults(suiteName: SharedGroupName)?.data(forKey: ServerChangeTokenKey) else { 
     return nil 
    } 

    return NSKeyedUnarchiver.unarchiveObject(with: encoded) as? CKServerChangeToken 
} 

然後初始化的對象:

 let zone = CKRecordZone(zoneName: "my_custom_zone_name") 
     let options = CKFetchRecordZoneChangesOptions() 
     options.previousServerChangeToken = serverChangeToken 

     let operation = CKFetchRecordZoneChangesOperation(recordZoneIDs: [zone.zoneID], optionsByRecordZoneID: [zone.zoneID: options]) 
0

即使使用權CKServerChangeToken,我遇到了這個錯誤,因爲我沒有控制數組changedZoneIDs有0個元素的情況。

嚴格來說,您需要兩個單獨的CKServerChangeToken來訪問數據庫更改和zoneChanges(比如說databaseChangeTokenzoneChangeToken)。您可以創建它們作爲巴特洛梅耶Semańczyk解釋

次使用recordZoneWithIDChangedBlock得到的了zoneid改變區域
次使用fetchDatabaseChangesCompletionBlock的保存databaseChangeToken,並呼籲在您使用zoneChangeToken的CKFetchRecordZoneChangesOperation,
- 每一個區域都有其自己changeToken所以我結束了此解決方案:

let operation = CKFetchDatabaseChangesOperation(previousServerChangeToken: databaseChangeToken) 
var changedZoneIDs: [CKRecordZoneID] = [] 

operation.recordZoneWithIDChangedBlock = { (zoneID) in 
    changedZoneIDs.append(zoneID) 
} 

operation.fetchDatabaseChangesCompletionBlock = { (databaseToken, moreComing, error) in 
{ 
    //manage moreComing 
    //save databaseToken 
    //manage error 

    if changedZoneIDs.count > 0 
    { 
     var optionsByRecordZoneID = [CKRecordZoneID: CKFetchRecordZoneChangesOptions]() 
     for zoneID in changedZoneIDs { 
      let changeTokenData = UserDefaults.standard.value(forKey: "\(zoneID.zoneName) zoneChangeToken") as? Data // Read change token from disk 
      var zoneChangeToken:CKServerChangeToken? 

      if (changeTokenData != nil){ 
       zoneChangeToken = NSKeyedUnarchiver.unarchiveObject(with: changeTokenData!)as! CKServerChangeToken? 
      } 
      let options = CKFetchRecordZoneChangesOptions() 
      options.previousServerChangeToken = zoneChangeToken 
      optionsByRecordZoneID[zoneID] = options 
     } 
     let operation = CKFetchRecordZoneChangesOperation(recordZoneIDs: changedZoneIDs, optionsByRecordZoneID: optionsByRecordZoneID) 

    // ... 
    }