在这里遵循答案:
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中拉出。我对其进行了更改,以使用扩展名,它通过了该扩展名,现在愉快地向我展示了错误提取区域更改消息,该消息应该出现在新问题中。

10-08 14:54