在这里遵循答案:
Save CKServerChangeToken to Core Data
当我尝试将新令牌保存为用户默认值时,代码失败。
我得到错误:
Could not cast value of type 'Foundation.__NSSwiftData' (0x1dad7a900) to 'CKServerChangeToken' (0x1da7fae08).
2019-07-28 12:05:41.594726-0700 HintApp[20235:1921952] Could not cast value of type 'Foundation.__NSSwiftData' (0x1dad7a900) to 'CKServerChangeToken' (0x1da7fae08).
只需将CKServerChangeToken保存为用户默认值Any。
public extension UserDefaults {
var serverChangeToken: CKServerChangeToken? {
get {
guard let data = self.value(forKey: changeTokenKey) as? Data else {
return nil
}
let token: CKServerChangeToken?
do {
token = try NSKeyedUnarchiver.unarchivedObject(ofClass: CKServerChangeToken.self, from: data)
} catch {
token = nil
}
return token
}
set {
if let token = newValue {
do {
let data = try NSKeyedArchiver.archivedData(withRootObject: token, requiringSecureCoding: true)
self.set(data, forKey: changeTokenKey)
} catch {
// handle error
print("error setting change token:\(error)")
}
} else {
self.removeObject(forKey: changeTokenKey)
}
}
}
}
接着
func fetchDatabaseChanges(database: CKDatabase, databaseTokenKey: String, completion: @escaping () -> Void) {
var changedZoneIDs: [CKRecordZone.ID] = []
let changeToken = UserDefaults.standard.serverChangeToken
let operation = CKFetchDatabaseChangesOperation(previousServerChangeToken: changeToken)
operation.recordZoneWithIDChangedBlock = { (zoneID) in
changedZoneIDs.append(zoneID)
}
operation.recordZoneWithIDWasDeletedBlock = { (zoneID) in
// Write this zone deletion to memory
}
operation.changeTokenUpdatedBlock = { (token) in
// Flush zone deletions for this database to disk
// Write this new database change token to memory
print("saving new token \(token)")
UserDefaults.standard.serverChangeToken = token
}
operation.fetchDatabaseChangesCompletionBlock = { (token, moreComing, error) in
if let error = error {
print("Error during fetch shared database changes operation", error)
completion()
return
}
// Flush zone deletions for this database to disk
// Write this new database change token to memory
self.fetchZoneChanges(database: database, databaseTokenKey: databaseTokenKey, zoneIDs: changedZoneIDs) {
// Flush in-memory database change token to disk
completion()
}
}
operation.qualityOfService = .userInitiated
database.add(operation)
}
结果:
saving new token <CKServerChangeToken: 0x2834ecf90; data=REDACTED==>
Could not cast value of type 'Foundation.__NSSwiftData' (0x1dad7a900) to 'CKServerChangeToken' (0x1da7fae08).
2019-07-28 12:05:41.594726-0700 HintApp[20235:1921952] Could not cast value of type 'Foundation.__NSSwiftData' (0x1dad7a900) to 'CKServerChangeToken' (0x1da7fae08).
**已编辑包含我不想在此处分享的实际数据。与我的错误无关。
最佳答案
对不起。我是个白痴。再往下一点,我试图将CKServerChangeToken直接从userDefaults中拉出。我对其进行了更改,以使用扩展名,它通过了该扩展名,现在愉快地向我展示了错误提取区域更改消息,该消息应该出现在新问题中。