CloudKit, после переустановки приложения, как мне восстановить мои подписки до текущего состояния записей? - PullRequest
0 голосов
/ 01 декабря 2018

Я имею дело со сценарием, в котором пользователь ранее удалил приложение и теперь переустанавливал его.

Это сбивало мою функцию дельта-выборки, которая получает много старых уведомлений о подписке, в основном удаляет.Но не загружаю текущие записи.

Сейчас я добавляю код для выполнения выборки для каждого типа записи, чтобы загрузить все данные.

Я хочу сбросить токен сервера дельта-выборки, поэтомуприложение не должно обрабатывать уведомления о старых подписках.Однако я не могу найти, как это сделать, возможно, это невозможно.

1 Ответ

0 голосов
/ 11 декабря 2018

Вы имеете в виду CKServerChangeToken ( документация ), когда говорите "токен сервера с дельта-выборкой"?И вы пытаетесь выполнить синхронизацию в базе данных CloudKit private ?

Предполагая, что это правда, вот пример того, как я получаю изменения из частной базы данных и отслеживаю токен синхронизации:

//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 в записи Users в CloudKit (вам придется добавить ее в качестве нового поля).Каждый раз, когда previousServerChangeToken изменяется в recordZoneFetchCompletionBlock, вам необходимо сохранять его обратно в iCloud в записи пользователя.

...