CloudKit,重新安装应用程序后,如何将我的订阅重置为记录的当前状态?

时间:2018-12-01 11:05:29

标签: ios cocoa-touch cloudkit cksubscription

我正在处理这种情况,即用户以前已删除该应用程序,现在已重新安装它。

它碰到了我的增量获取功能,该功能正在接收许多旧的订阅通知,大部分是删除通知。但不下载当前记录。

我现在要添加代码以对每种记录类型执行提取以下载所有数据。

我想重置增量获取服务器令牌,因此该应用程序不必处理旧的订阅通知。但是我找不到如何做到这一点,也许这是不可能的。

1 个答案:

答案 0 :(得分:0)

当您说“增量获取服务器令牌”时,您是指CKServerChangeTokendocumentation)吗?并且您是否正在尝试在CloudKit 私有数据库中进行同步?

假设是真的,这是我如何从私有数据库中获取更改并跟踪同步令牌的示例:

//MARK: Fetch Latest from CloudKit from private DB
func fetchPrivateCloudKitChanges(){
  print("Fetching private changes...")

  //:::
  let privateZoneId = CKRecordZone.ID(zoneName: CloudKit.zoneName, ownerName: CKCurrentUserDefaultName)

  /----
  let options = CKFetchRecordZoneChangesOperation.ZoneOptions()
  options.previousServerChangeToken = previousChangeToken

  let operation = CKFetchRecordZoneChangesOperation(recordZoneIDs: [privateZoneId], optionsByRecordZoneID: [recordZoneID:options])

  //Queue up the updated records to process below
  var records = [CKRecord]()

  operation.recordChangedBlock = { record in
    records.append(record)
  }

  operation.recordWithIDWasDeletedBlock = { recordId, type in
    //Process a deleted record in your local database...
  }

  operation.recordZoneChangeTokensUpdatedBlock = { (zoneId, token, data) in
    // Save new zone change token to disk
    previousChangeToken = token
  }

  operation.recordZoneFetchCompletionBlock = { zoneId, token, _, _, error in
    if let error = error {
      print(error)
    }
    // Write this new zone change token to disk
    previousChangeToken = token
  }

  operation.fetchRecordZoneChangesCompletionBlock = { error in
    if let error = error {
      print(error
    }else{
      //Success! Process all downloaded records from `records` array above...
      //records...
    }
  }

  CloudKit.privateDB.add(operation)
}

//Change token property that gets saved and retrieved from UserDefaults
var previousChangeToken: CKServerChangeToken? {
  get {
    guard let tokenData = defaults.object(forKey: "previousChangeToken") as? Data else { return nil }
    return NSKeyedUnarchiver.unarchiveObject(with: tokenData) as? CKServerChangeToken
  }
  set {
    guard let newValue = newValue else {
      defaults.removeObject(forKey: "previousChangeToken")
      return
    }

    let data = NSKeyedArchiver.archivedData(withRootObject: newValue)
    defaults.set(data, forKey: "previousChangeToken")
  }
}

您的具体情况可能会有所不同,但是我认为这通常是要与CloudKit保持同步的方式。

更新

您可以尝试将previousServerChangeToken存储在CloudKit的Users记录中(您必须将其添加为新字段)。每次previousServerChangeToken中的recordZoneFetchCompletionBlock更改时,您都必须将其保存回用户记录中的iCloud中。