【发布时间】:2019-09-29 13:51:34
【问题描述】:
我希望使用 NSKeyedArchiver 将包含字典的 swift 结构保存到数据中。我使用 NSKeyedArchiver 的原因是因为字典有一个与之关联的不可编码变量。我正在关注来自Paul Hudson 的本指南。
我遇到的问题是我不断收到错误消息“无法写入数据,因为它的格式不正确。”在“让编码=尝试编码器。编码(测试) " 这似乎适用于不可编码的类型,但当它们在 dictovnay 中时则不行。有没有人知道如何让它工作?这里是代码:
import SwiftUI
import Combine
import HealthKit
struct Testing: View {
func saveData(){
let test = TestHealthSample(
myHKUnit : [Unit.imperial : HKUnit.kilocalorie(), Unit.metric : HKUnit.kilocalorie()],
isFavorite: true
)
let encoder = JSONEncoder()
do {
let encoded = try encoder.encode(test)
let str = String(decoding: encoded, as: UTF8.self)
print(str)
} catch {
print(error.localizedDescription)
}
}
var body: some View {
Text("Test")
.onAppear{
self.saveData()
}
}
}
struct TestHealthSample{
var myHKUnit : [Unit: HKUnit]
var isFavorite : Bool
}
extension TestHealthSample: Codable {
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: TestCodingKeys.self)
isFavorite = try container.decode(Bool.self, forKey: .isFavorite)
let hkUnitData = try container.decode(Data.self, forKey: .myHKUnit)
myHKUnit = try (NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(hkUnitData) as? [Unit:HKUnit]) ?? [Unit.metric : HKUnit.count()]
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: TestCodingKeys.self)
try container.encode(isFavorite, forKey: .isFavorite)
let hkUnitData = try NSKeyedArchiver.archivedData(withRootObject: myHKUnit, requiringSecureCoding: false)
try container.encode(hkUnitData, forKey: .myHKUnit)
}
}
enum TestCodingKeys: String, CodingKey {
case myHKUnit
case isFavorite
}
enum Unit : String, Codable{
case metric
case imperial
}
【问题讨论】:
-
将
print(error.localizedDescription)更改为print(error)以获取更多详细信息。 -
不幸的是,这并没有起到多大作用。它在归档期间吐出 UserInfo={NSDebugDescription=Caught 异常:-[__SwiftValue encodeWithCoder:]: unrecognized selector sent to instance 0x283e45ef0 (..... 然后是一堆文本。
-
您混淆了
Codable和NSCoding。后者根本不适用于结构。删除NSKeyedArchiver并仅使用Codable -
@vadian 我会但是 "var myHKUnit : [Unit: HKUnit]" 包含 HKUnit 这是一个不可编码的类型
-
尽可能使其符合
Codable或编写包装器。
标签: swift dictionary nskeyedarchiver