将CloudKit记录保存到本地文件中保存除CKAsset以外的所有字段

时间:2019-01-25 04:41:00

标签: ios cloudkit ckasset nsarchiving

我正在尝试将CKRecords数组保存到以下位置的documents目录中 以便快速启动和脱机访问。

从CloudKit下载CKRecords可以正常工作,我可以在每个记录中使用CKAsset而没有问题。但是,当我将下载的CKRecords数组保存到本地文件时,CKAsset不包含在数据文件中。从保存到文档目录中的文件大小可以看出这一点。如果将磁盘文件重构为CKRecords数组,则可以检索除CKAsset之外的所有字段。除了系统字段和CKAsset字段外,所有字段都是字符串。

为了进行测试-我有10个CloudKit记录,每个记录都有6个小的String字段 以及大约500KB的CKAsset。当我检查尺寸时 文件中生成的文件的文件大小约为15KB。

这是保存数组的功能。 AppDelegate.ckStyleRecords是一个 下载的CKRecords的静态数组。

func saveCKStyleRecordsToDisk() {

    if AppDelegate.ckStyleRecords.count != 0 {

        let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        let docsDirectoryURL = urls[0]
        let ckStyleURL = docsDirectoryURL.appendingPathComponent("ckstylerecords.data")

        do {
            let data : Data = try NSKeyedArchiver.archivedData(withRootObject: AppDelegate.ckStyleRecords, requiringSecureCoding: true)

            try data.write(to: ckStyleURL, options: .atomic)
            print("data write ckStyleRecords successful")

        } catch {
            print("could not save ckStyleRecords to documents directory")
        }

    }//if count not 0

}//saveCKStyleRecordsToDisk

这是重构数组的功能。

func checkForExistenceOfCKStyleRecordsInDocuments(completion: @escaping ([CKRecord]) -> Void) {

    let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    let docsDirectoryURL = urls[0]
    let ckStyleURL = docsDirectoryURL.appendingPathComponent("ckstylerecords.data")

    var newRecords : [CKRecord] = []
    if FileManager.default.fileExists(atPath: ckStyleURL.path) {

        do {
            let data = try Data(contentsOf:ckStyleURL)

            //yes, I know this has been deprecated, but I can't seem to get the new format to work
            if let theRecords: [CKRecord] = try NSKeyedUnarchiver.unarchiveObject(with: data) as? [CKRecord] {
                        newRecords = theRecords
                        print("newRecords.count is \(newRecords.count)")
            }

        } catch {
            print("could not retrieve ckStyleRecords from documents directory")
        }

    }//if exists

    completion(newRecords)

}//checkForExistenceOfckStyleRecordsInDocuments

打电话给上面

    kAppDelegate.checkForExistenceOfCKStyleRecordsInDocuments { (records) in
        print("in button press and records.count is \(records.count)")

        //this is just for test
        for record in records {
            print(record.recordID.recordName)
        }

        AppDelegate.ckStyleRecords = records

    }//completion block

刷新使用ckStyleRecords数组的tableView时,所有数据 似乎正确,除了CKAsset(在这种情况下为SceneKit) 场景)当然会丢失。

任何指导将不胜感激。

1 个答案:

答案 0 :(得分:0)

CKAsset只是文件引用。 CKAsset的fileURL属性是实际文件所在的位置。如果保存一个SKAsset,则仅保存对该文件的引用。这样做时,您必须记住该URL位于缓存位置,如果空间不足,则可以清除该URL。

您可以做两件事。 1.在读取备份CKAset时,还要检查文件是否位于fileURL位置。如果文件不存在,请从CloudKit再次读取。 2.还将文件从fileURl备份到您的documents文件夹。当您从备份中读取CKAset时,只需不从fileURL中读取文件,而是从文档过滤器中放置文件的位置即可。

相关问题