在CKFetchRecordChangesOperation上有很多变化,这是正常的吗?

时间:2016-02-15 12:27:19

标签: ios icloud cloudkit ckfetchrecordchangesopera

我在我的应用中使用CloudKit,这似乎运作良好。但是,当我在新设备上初始化应用程序时,使用

CKFetchRecordChangesOperation *fetchRecordChangesOperation = [[CKFetchRecordChangesOperation alloc] initWithRecordZoneID:zoneID previousServerChangeToken:NIL];

我收到很多更改,因为所有以前的删除和更改似乎都会同步。

有更好的方法吗?例如,只需下载一整套当前数据并将serverChangeToken设置为当前值。

1 个答案:

答案 0 :(得分:1)

在查看CKServerChangeToken的文档时,看起来你只能在使用CKFetchRecordChangesOperation时获取它。请参阅:https://developer.apple.com/library/prerelease/ios/documentation/CloudKit/Reference/CKServerChangeToken_class/index.html

那么现在你怎么能抓住这个标记:

通常你会这样做:正如你在CKFetchRecordChangesOperation中看到的那样,你可以用previousServerChangeToken初始化它。此令牌的作用类似于时间戳。操作完成后,您将在fetchRecordChangesCompletionBlock中获取此令牌。您必须将该令牌保存在例如用户默认值中。然后,下次启动CKFetchRecordChangesOperation时,您可以使用该令牌开始读取自上次调用后的更改。

实际上保存令牌可能有点棘手。我可以建议添加这样的属性:

private var previousChangeToken: CKServerChangeToken? {
    get {

        let encodedObjectData = NSUserDefaults.standardUserDefaults().objectForKey("\(container.containerIdentifier)_lastFetchNotificationId") as? NSData
        var decodedData: CKServerChangeToken? = nil
        if encodedObjectData != nil {
            decodedData = NSKeyedUnarchiver.unarchiveObjectWithData(encodedObjectData!) as? CKServerChangeToken
        }
        return decodedData
    }
    set(newToken) {
        if newToken != nil {
            NSUserDefaults.standardUserDefaults().setObject(NSKeyedArchiver.archivedDataWithRootObject(newToken!), forKey:"\(container.containerIdentifier)_lastFetchNotificationId")
        }
    }
}

在您的情况下,您希望新应用程序以一个只能由其他正在运行的应用程序创建的更改令牌开始。因此,除了将更改令牌保存到NSUserDefaults之外,还应将其保存在公共数据库中的CloudKit中的一个特定设置recordType记录中。然后,新安装的应用程序中没有令牌的NSUserDefaults可以从您的CloudKit设置记录中读取令牌。