将CKServerChangeToken保存到核心数据 [英] Save CKServerChangeToken to Core Data

查看:157
本文介绍了将CKServerChangeToken保存到核心数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将CloudKit和Core Data与Swift一起使用来同步我的数据。因此,我创建了订阅,并在收到通知后从云中获取新数据以更新我的核心数据。这是处理此更新的推荐方法。为了获取数据更改,我可以插入CKServerChangeToken以仅获取新内容。我的问题是如何将令牌保存到Core Data以便以后进行提取请求?对于CKRecords,有一种方法只能保存元数据,但对于CKServerChangeToken则没有这样的功能。有人有想法吗?

I use CloudKit and Core Data with Swift to synchronize my data. Therefore I created Subscriptions and after getting a notification I fetch the new data from the cloud to update my Core Data. This is the recommended way to handle this update. For fetching data changes I can insert a CKServerChangeToken to fetch just the new stuff. My question is how to save the token to Core Data for later fetch requests? For CKRecords there is a method to save only the metadata but there isn't anything like this for CKServerChangeToken. Does anyone have an idea?

最好的问候,扬尼克

推荐答案

CKServerChangeToken是一个不透明的数据对象,它继承自NSObject并符合NSCopying协议,这意味着您可以使用NSKeyedArchiver和NSKeyedUnarchiver将令牌转换为(NS)Data对象。

The CKServerChangeToken is an opaque data object that inherits from NSObject and conforms to the NSCopying protocol, which means that you can use a NSKeyedArchiver and NSKeyedUnarchiver to convert the token to an (NS)Data object.

一个(NS)Data对象存储到任何NSManagedObject的属性中。或者,您可以将此数据存储在(NS)UserDefaults中。这是快速完成UserDefaults扩展的一种方法:

A (NS)Data object can then be stored into a property on any NSManagedObject. Alternatively you could store this data in the (NS)UserDefaults. Here's one way to accomplish this as a swift extension to UserDefaults:

import Foundation
import CloudKit

public extension UserDefaults {

    public var serverChangeToken: CKServerChangeToken? {
        get {
            guard let data = self.value(forKey: "ChangeToken") as? Data else {
                return nil
            }

            guard let token = NSKeyedUnarchiver.unarchiveObject(with: data) as? CKServerChangeToken else {
                return nil
            }

            return token
        }
        set {
            if let token = newValue {
                let data = NSKeyedArchiver.archivedData(withRootObject: token)
                self.set(data, forKey: "ChangeToken")
            } else {
                self.removeObject(forKey: "ChangeToken")
            }
        }
    }
}

使用此扩展名,您可以从(NS)UserDefaults正确获取/设置CKServerChangeToken,

With this extension you can get/set the CKServerChangeToken right from (NS)UserDefaults with:

let changeToken = UserDefaults.standard.serverChangeToken
UserDefaults.standard.serverChangeToken = `newToken`






As指出,iOS 12中不推荐使用NSKeyedUn / Archiver调用。这是一个更新的示例。


As pointed out, the NSKeyedUn/Archiver calls were deprecated in iOS 12. Here is an updated example.

import Foundation
import CloudKit

public extension UserDefaults {

    public var serverChangeToken: CKServerChangeToken? {
        get {
            guard let data = self.value(forKey: "ChangeToken") 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: false)
                self.set(data, forKey: "ChangeToken")
                } catch {
                    // handle error
                }
            } else {
                self.removeObject(forKey: "ChangeToken")
            }
        }
    }
}

这篇关于将CKServerChangeToken保存到核心数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆