-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Time fails to decode array of Time.Signature
Based on Time.Measured implementations
public struct Measured {
// FIXME:
var values: [Time.Signature]
var interchangeable: Interchangeable?
public init(_ values: [Time.Signature], interchangeable: Interchangeable? = nil) {
self.values = values
self.interchangeable = interchangeable
}
}& based on Time's elements in a common MusicXML
<time symbol="single-number">
<beats>1</beats>
<beat-type>8</beat-type>
<beats>2</beats>
<beat-type>4</beat-type>
</time>The array of Time.Signature is certainly an unkeyed element since no keys for this variable exist in a MusicXML file.
Unkeyed element of type [Signature] in Measured fails to be decoded
extension Time.Measured: Codable {
enum CodingKeys: String, CodingKey {
// case signature
case interchangeable
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: Time.Measured.CodingKeys.self)
self.values = try decoder.collectArray()
self.interchangeable = try container.decodeIfPresent(Interchangeable.self, forKey: .interchangeable)
}
}The line self.values = try decoder.collectArray() should be able to decode the array of `[Time.Signature] but throws an error in the debugger:
error: -[SwiftMXLTests.TimeTests testDecodingMeasured] : failed: caught error:
"typeMismatch(Swift.Dictionary<Swift.String, Any>,
Swift.DecodingError.Context(codingPath:
[XMLKey(stringValue: "0", intValue: 0),
XMLKey(stringValue: "0", intValue: 0)],
debugDescription: "Expected to decode Dictionary<String, Any> but found ChoiceBox instead.",
underlyingError: nil)
)"I currently don't know what is wrong, but I have two options right now:
1. A Workaround
2. Investigate the thrown error
The Workaround
Currently, instead of decoding an array of Signature, I decoded an array of beats an another array for beatType.
This would decode the data in the following way:
decoded:
Measured(signature: [SwiftMXL.Time.Signature(beats: ["3", "1"], beatType: ["4", "8"])], interchangeable: nil)The workaround would be to write some logic for the decoded beats & beatTypes that would initialize an array of Time.Signature with the number of elements based on the count of beats & then return the decoded data using the created array.
Though it isn't a very convenient approach, it'll work at least for the decode process.
The Investigation
Involves more debugging & more reading for me unless some one with more skills identifies the issue & makes my life easier.