Reputation: 36003
I am creating a class that conforms to codable.
I have this:
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)
}
}
This is apparently fine.
I create an instance of Attribute
and encode it using:
let newAttribute = Attribute.init(number:value.number, label:value.label, comments:value.shortcut)
Then I create an array of these attributes and encode that array using
let array = try JSONEncoder().encode(array)
This will encode the array of Attribute
to Data
.
Then I try to convert the Data
object back to the array of Attribute
using this:
let array = try JSONDecoder().decode(Attribute.self, from: data) as! Array<Attribute>
First error I get is this:
Cast from 'Attribute' to unrelated type 'Array< Attribute>' always fails
If I remove the cast part I catch this error when the decode tries...
Optional("The data isn’t in the correct format.")
Any ideas?
Upvotes: 0
Views: 1305
Reputation: 54755
You need to pass in the array to decode, don't pass in the array element type, then try to force-cast that to an array, that doesn't make any sense. YourType
and Array<YourType>
are two different and completely unrelated types, so you cannot cast one to the other and you need to use the specific type when calling JSONDecoder.decode(_:from:)
.
let array = try JSONDecoder().decode([Attribute].self, from: data)
Btw as already pointed out in your previous question, there is no need to manually write the init(from:)
and encode(to:)
methods or the CodingKeys
enum
since for your simple type, the compiler can auto-synthesise all of those for you. Also, if you used a struct
instead of class
, you'd also get the member wise initialiser for free.
Upvotes: 2