是否可以将CKRecord.encodeSystemFields与JSONEncoder一起使用

问题描述 投票:1回答:1

我在“How (and when) do I use iCloud's encodeSystemFields method on CKRecord?”中看到如何使用NSKeyedArchiver来缓存CKRecord的显着字段。有没有办法将JSONEncoder与encodeSystemFields一起使用?我的其他缓存数据保存为JSON,所以我希望encodeSystemFields适合它。

不幸的是Data不允许使用有效的JSON,尽管是Codable,并且未通过测试JSONSerialization.isValidJSONObject,所以我不能将NSKeyedArchiver的输出堵塞到我的JSON序列化中。

let d = Data()
d is Codable // true
// ...encodeSystemFields...
JSONSerialization.isValidJSONObject([d]) // false
let listofd = [d]
JSONSerialization.isValidJSONObject(listofd) // false
let dictofd = ["test":d]
JSONSerialization.isValidJSONObject(dictofd) // false

如果dDataNSMutableData无关紧要。我得到了相同的结果。

ios json swift cloudkit foundation
1个回答
1
投票

我发现的解决方案是首先使用NSKeyedArchiver序列化为NSMutableData,将其强制转换为Data,然后使用JSONEncoder将其再次编码为JSON。它创建的JSON少于2000个字节。这压倒了我的小记录,但这就是生活。

这是一个工作场所:

import Foundation
import CloudKit

let zoneID1 = CKRecordZoneID(zoneName: "Test.1",
                             ownerName: CKCurrentUserDefaultName)
let recID1 = CKRecordID(recordName: "Test1",
                        zoneID: zoneID1)
let rec1 = CKRecord(recordType: "Test",
                    recordID: recID1)

let cacheNSData = NSMutableData()
let kArchiver = NSKeyedArchiver(forWritingWith: cacheNSData)
rec1.encodeSystemFields(with: kArchiver)
kArchiver.finishEncoding()

cacheNSData.length
let cacheData = cacheNSData as Data

let jEncoder = JSONEncoder()

struct Cache: Codable {
    var title: String
    var blob: Data
}
let cacheItem = Cache(title: "abc", blob: cacheData)

let jData = try jEncoder.encode(cacheItem)
jData.count

String(data: jData, encoding: .utf8)
© www.soinside.com 2019 - 2024. All rights reserved.