WrapperOfNSCoding失败,只有一个值 [英] WrapperOfNSCoding fails with single value
问题描述
struct WrapperOfNSCoding<Wrapped>: Codable where Wrapped: NSCoding {
var wrapped: Wrapped
init(_ wrapped: Wrapped) { self.wrapped = wrapped }
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let data = try container.decode(Data.self)
guard let object = NSKeyedUnarchiver.unarchiveObject(with: data) else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "failed to unarchive an object")
}
guard let wrapped = object as? Wrapped else {
throw DecodingError.typeMismatch(Wrapped.self, DecodingError.Context(codingPath: container.codingPath, debugDescription: "unarchived object type was \(type(of: object))"))
}
self.wrapped = wrapped
}
func encode(to encoder: Encoder) throws {
let data = NSKeyedArchiver.archivedData(withRootObject: wrapped)
var container = try encoder.singleValueContainer()
try container.encode(data)
}
}
let colors = [NSColor.red, NSColor.brown]
print(colors)
let w = WrapperOfNSCoding(colors[0])
let jsonData = try! JSONEncoder().encode(w) - fails
let jsonData = try! JSONEncoder().encode(colors.map({ WrapperOfNSCoding($0) })) - succeeds
print(jsonData)
let colors2 = try! JSONDecoder().decode([WrapperOfNSCoding<NSColor>].self, from: jsonData).map({ $0.wrapped })
print(colors2)
错误是在编码器中使用单个值时
The error is when a single value is used in the encoder
let w = WrapperOfNSCoding(colors[0])
let jsonData = try! JSONEncoder().encode(w)
错误是
致命错误:尝试!表达式意外引发错误:
Swift.EncodingError.invalidValue(WrapperOfNSCoding#1 ...
Fatal error: 'try!' expression unexpectedly raised an error: Swift.EncodingError.invalidValue(WrapperOfNSCoding #1...
成功
let w = WrapperOfNSCoding([colors[0]])
let jsonData = try! JSONEncoder().encode(w)
为什么是
推荐答案
JSONEncoder
在顶层需要有效的JSON上下文,可以是 [:]
(字典)或 []
(数组),您可以在其中放置一个元素,例如此示例字符串
。
JSONEncoder
need valid JSON context on the top level, which could be either [:]
(Dictionary) or []
(Array), inside you can place an element like in this example string
.
保存任何 NSCoding
对象,编译器将该对象视为字符串。对于 JSONEncoder()。encode(w)
,您正在尝试对 NSCoding进行编码
对象,它充当 string
对象,而不是常规的 JSON
对象。
When you save any NSCoding
object, the compiler treats that object as the string. In the case of JSONEncoder().encode(w)
, you are trying to encode an NSCoding
object which acts as a string
object instead of regular JSON
object.
对于 JSONEncoder()。encode([w])
,对象创建了一个数组,在您的情况下,每个元素都有一个字符串,该字符串为 NSCoding
。
In the case of JSONEncoder().encode([w])
, the object has created an array and each element has a string which is NSCoding
in your case.
以另一种方式 w
数据是一个字符串,而 [w]
是一个数组,每个索引都有一个字符串,因此 JSONEncoder
不会为您提供错误的 [w]
,并给您 w
的错误。
In another way w
data is a string and [w]
is an array with each index is having a string, therefore JSONEncoder
is not giving you an error with [w]
and giving you an error for w
.
这篇关于WrapperOfNSCoding失败,只有一个值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!