【问题标题】:How to initialise CKFetchRecordZoneChangesOperation with previousServerchangetoken?如何使用 previousServerchangetoken 初始化 CKFetchRecordZoneChangesOperation?
【发布时间】:2017-02-10 13:21:27
【问题描述】:

我正在从 CloudKit 服务器获取记录更改,但每次出现错误

[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}];**

【问题讨论】:

    标签: ios iphone xcode objective-c-blocks cloudkit


    【解决方案1】:

    只需创建变量:

    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])
    

    【讨论】:

      【解决方案2】:

      即使使用正确的 CKServerChangeToken,我也遇到了这个错误,因为我没有控制数组 changedZoneIDs 有 0 个元素的情况。

      严格来说,您需要两个单独的 CKServerChangeToken 来访问数据库更改和 zoneChanges(比如说 databaseChangeTokenzoneChangeToken)。您可以按照 Bartłomiej 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)
      
          // ...
          }
      

      【讨论】:

      • 尤里卡!我错过了 zoneToken 和 databaseToken 是不同令牌的概念。
      猜你喜欢
      • 1970-01-01
      • 2017-03-24
      • 2020-08-02
      • 2017-11-06
      • 2012-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多