无法使用 NSKeyedArchiver 保存我的模型
Cannot use NSKeyedArchiver to save my model
我正在从 Api 获取模型,它看起来像这样:
class Device : NSObject, Codable, NSCoding{
var deviceId : Int?
var driver : String?
var address : String?
var type : DeviceTypes? // Enum type
func encode(with coder: NSCoder) {
coder.encode(self.deviceId, forKey: "deviceId")
coder.encode(self.driver, forKey: "driver")
coder.encode(self.address, forKey: "address")
coder.encode(self.type, forKey: CodingKeys.type.rawValue)
}
required init?(coder: NSCoder) {
super.init()
self.deviceId = coder.decodeInteger(forKey: "deviceId")
self.driver = coder.decodeObject(forKey: "driver") as? String
self.address = coder.decodeObject(forKey: "address") as? String
self.type = coder.decodeObject(forKey: CodingKeys.type.rawValue) as? DeviceTypes
}
private enum CodingKeys : String, CodingKey{
case deviceId, address, type, deviceType
}
}
然后我将一些元素添加到数组并且它有效但是当我尝试使用 NSKeyedArchiver 将它存档时它抛出异常:
[__SwiftValue encodeWithCoder:]: 无法识别的选择器发送到实例
设备类型
enum DeviceTypes : Int, Codable{
case SYSTEM
case CE
case CZ
case ST
case KA
case CR
case EX
case DR
case KL
case WE
case WY
case WL
case TR
case LI
case BR = 30
case DC = 32
}
您的问题是 NSCoding
仅适用于 class 类型。任何使 DeviceTypes
符合 NSCoding
的尝试都将导致错误
enum DeviceTypes : Int, Codable, NSCoding {
Non-class type 'DeviceTypes' cannot conform to class protocol 'NSCoding'
一个解决方案是在 NSCoding
方法中来回转换 enum
类型。
请注意 NSCoding
已针对 NSSecureCoding
软弃用,因此您应该使用该一致性以避免将来出现支持问题。
class Device : NSObject, NSSecureCoding {
static var supportsSecureCoding: Bool = true
var deviceId : Int?
var driver : String?
var address : String?
var type : DeviceTypes? // Enum type
func encode(with coder: NSCoder) {
coder.encode(self.deviceId, forKey: "deviceId")
coder.encode(self.driver, forKey: "driver")
coder.encode(self.address, forKey: "address")
coder.encode(self.type?.rawValue, forKey: "type")
}
required init?(coder: NSCoder) {
super.init()
self.deviceId = coder.decodeInteger(forKey: "deviceId")
self.driver = coder.decodeObject(forKey: "driver") as? String
self.address = coder.decodeObject(forKey: "address") as? String
let rawtype = coder.decodeInteger(forKey: "type")
self.type = DeviceTypes(rawValue: rawtype)
}
}
您没有在 Device
class 中提供所有代码,因为您的 post 片段没有按照 Codable
一致性进行编译,所以我无法猜测就 JSON 支持而言,您的系统真正需要什么。
我正在从 Api 获取模型,它看起来像这样:
class Device : NSObject, Codable, NSCoding{
var deviceId : Int?
var driver : String?
var address : String?
var type : DeviceTypes? // Enum type
func encode(with coder: NSCoder) {
coder.encode(self.deviceId, forKey: "deviceId")
coder.encode(self.driver, forKey: "driver")
coder.encode(self.address, forKey: "address")
coder.encode(self.type, forKey: CodingKeys.type.rawValue)
}
required init?(coder: NSCoder) {
super.init()
self.deviceId = coder.decodeInteger(forKey: "deviceId")
self.driver = coder.decodeObject(forKey: "driver") as? String
self.address = coder.decodeObject(forKey: "address") as? String
self.type = coder.decodeObject(forKey: CodingKeys.type.rawValue) as? DeviceTypes
}
private enum CodingKeys : String, CodingKey{
case deviceId, address, type, deviceType
}
}
然后我将一些元素添加到数组并且它有效但是当我尝试使用 NSKeyedArchiver 将它存档时它抛出异常:
[__SwiftValue encodeWithCoder:]: 无法识别的选择器发送到实例
设备类型
enum DeviceTypes : Int, Codable{
case SYSTEM
case CE
case CZ
case ST
case KA
case CR
case EX
case DR
case KL
case WE
case WY
case WL
case TR
case LI
case BR = 30
case DC = 32
}
您的问题是 NSCoding
仅适用于 class 类型。任何使 DeviceTypes
符合 NSCoding
的尝试都将导致错误
enum DeviceTypes : Int, Codable, NSCoding {
Non-class type 'DeviceTypes' cannot conform to class protocol 'NSCoding'
一个解决方案是在 NSCoding
方法中来回转换 enum
类型。
请注意 NSCoding
已针对 NSSecureCoding
软弃用,因此您应该使用该一致性以避免将来出现支持问题。
class Device : NSObject, NSSecureCoding {
static var supportsSecureCoding: Bool = true
var deviceId : Int?
var driver : String?
var address : String?
var type : DeviceTypes? // Enum type
func encode(with coder: NSCoder) {
coder.encode(self.deviceId, forKey: "deviceId")
coder.encode(self.driver, forKey: "driver")
coder.encode(self.address, forKey: "address")
coder.encode(self.type?.rawValue, forKey: "type")
}
required init?(coder: NSCoder) {
super.init()
self.deviceId = coder.decodeInteger(forKey: "deviceId")
self.driver = coder.decodeObject(forKey: "driver") as? String
self.address = coder.decodeObject(forKey: "address") as? String
let rawtype = coder.decodeInteger(forKey: "type")
self.type = DeviceTypes(rawValue: rawtype)
}
}
您没有在 Device
class 中提供所有代码,因为您的 post 片段没有按照 Codable
一致性进行编译,所以我无法猜测就 JSON 支持而言,您的系统真正需要什么。