试图在 Swift 中使 class 可编码,但它的格式不正确?
Trying to make a class codable in Swift but it is not the correct format?
我正在创建一个符合 codable 的 class。
我有这个:
import Foundation
class Attribute : Decodable {
var number: Int16
var label: String?
var comments: String?
init(number:Int16, label:String?, comments:String?) {
self.number = number
self.label = label
self.comments = comments
}
// Everything from here on is generated for you by the compiler
required init(from decoder: Decoder) throws {
let keyedContainer = try decoder.container(keyedBy: CodingKeys.self)
number = try keyedContainer.decode(Int16.self, forKey: .number)
label = try keyedContainer.decode(String.self, forKey: .label)
comments = try keyedContainer.decode(String.self, forKey: .comments)
}
enum CodingKeys: String, CodingKey {
case number
case label
case comments
}
}
extension Attribute: Encodable {
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(number, forKey: .number)
try container.encode(label, forKey: .label)
try container.encode(comments, forKey: .comments)
}
}
这显然没问题。
我创建了一个 Attribute
的实例并使用以下代码对其进行编码:
let newAttribute = Attribute.init(number:value.number, label:value.label, comments:value.shortcut)
然后我创建一个包含这些属性的数组并使用
对该数组进行编码
let array = try JSONEncoder().encode(array)
这会将 Attribute
的数组编码为 Data
。
然后我尝试使用以下方法将 Data
对象转换回 Attribute
的数组:
let array = try JSONDecoder().decode(Attribute.self, from: data) as! Array<Attribute>
我得到的第一个错误是:
Cast from 'Attribute' to unrelated type 'Array< Attribute>' always fails
如果我删除演员表,我会在解码尝试时捕获此错误...
Optional("The data isn’t in the correct format.")
有什么想法吗?
你需要传入数组来解码,不要传入数组元素类型,然后尝试将其强制转换为数组,这没有任何意义。 YourType
和 Array<YourType>
是两种不同的、完全不相关的类型,因此不能将一个转换为另一个,调用 JSONDecoder.decode(_:from:)
时需要使用特定的类型。
let array = try JSONDecoder().decode([Attribute].self, from: data)
顺便说一句,正如您在上一个问题中已经指出的那样,没有必要手动编写 init(from:)
和 encode(to:)
方法或 CodingKeys
enum
因为您简单类型,编译器可以为你自动合成所有这些。此外,如果您使用 struct
而不是 class
,您还可以免费获得成员智能初始化程序。
我正在创建一个符合 codable 的 class。
我有这个:
import Foundation
class Attribute : Decodable {
var number: Int16
var label: String?
var comments: String?
init(number:Int16, label:String?, comments:String?) {
self.number = number
self.label = label
self.comments = comments
}
// Everything from here on is generated for you by the compiler
required init(from decoder: Decoder) throws {
let keyedContainer = try decoder.container(keyedBy: CodingKeys.self)
number = try keyedContainer.decode(Int16.self, forKey: .number)
label = try keyedContainer.decode(String.self, forKey: .label)
comments = try keyedContainer.decode(String.self, forKey: .comments)
}
enum CodingKeys: String, CodingKey {
case number
case label
case comments
}
}
extension Attribute: Encodable {
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(number, forKey: .number)
try container.encode(label, forKey: .label)
try container.encode(comments, forKey: .comments)
}
}
这显然没问题。
我创建了一个 Attribute
的实例并使用以下代码对其进行编码:
let newAttribute = Attribute.init(number:value.number, label:value.label, comments:value.shortcut)
然后我创建一个包含这些属性的数组并使用
对该数组进行编码 let array = try JSONEncoder().encode(array)
这会将 Attribute
的数组编码为 Data
。
然后我尝试使用以下方法将 Data
对象转换回 Attribute
的数组:
let array = try JSONDecoder().decode(Attribute.self, from: data) as! Array<Attribute>
我得到的第一个错误是:
Cast from 'Attribute' to unrelated type 'Array< Attribute>' always fails
如果我删除演员表,我会在解码尝试时捕获此错误...
Optional("The data isn’t in the correct format.")
有什么想法吗?
你需要传入数组来解码,不要传入数组元素类型,然后尝试将其强制转换为数组,这没有任何意义。 YourType
和 Array<YourType>
是两种不同的、完全不相关的类型,因此不能将一个转换为另一个,调用 JSONDecoder.decode(_:from:)
时需要使用特定的类型。
let array = try JSONDecoder().decode([Attribute].self, from: data)
顺便说一句,正如您在上一个问题中已经指出的那样,没有必要手动编写 init(from:)
和 encode(to:)
方法或 CodingKeys
enum
因为您简单类型,编译器可以为你自动合成所有这些。此外,如果您使用 struct
而不是 class
,您还可以免费获得成员智能初始化程序。