我在“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序列化中。 / p>
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
d
是Data
还是NSMutableData
并不重要。我得到了相同的结果。
答案 0 :(得分: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)