|
|
| Previous ID |
SR-5953 |
| Radar |
rdar://problem/37316307 |
| Original Reporter |
cocoahero (JIRA User) |
| Type |
Improvement |
Attachment: Download
Additional Detail from JIRA
|
|
| Votes |
26 |
| Component/s |
Foundation |
| Labels |
Improvement |
| Assignee |
None |
| Priority |
Medium |
md5: 8e5158944f566da394566f3054ff764a
Issue Description:
In the current implementation of Decodable, it is impossible to attempt to decode an array of Decodable's and allow individual items to fail.
For example:
enum Season: String, Decodable {
case winter
case spring
case summer
case autumn
}
let json = """
["winter", "spring", "summer", "fall"]
""".data(using: .utf8)!
let seasons = try! JSONDecoder().decode([Season].self, from: json)
This will raise an error of the following:
Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [Foundation.(_JSONKey in _12768CA107A31EF2DCE034FD75B541C9)(stringValue: "Index 3", intValue: Optional(3))], debugDescription: "Cannot initialize Season from invalid String value fall", underlyingError: nil))
It may be considered desirable in certain use cases that this decode succeeds, but omits individual items that fail. As such, the desired output value would be:
[.winter, .spring. summer]
One may attempt to circumvent this by using an outer, wrapper type combined with a customized initializer that ignores inner decode errors, such as the following:
struct Climate: Decodable {
var seasons: [Season]
enum CodingKeys: String, CodingKey {
case seasons
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
var seasonsContainer = try container.nestedUnkeyedContainer(forKey: .seasons)
var seasons = [Season]()
while !seasonsContainer.isAtEnd {
if let season = try? seasonsContainer.decode(Season.self) {
seasons.append(season)
}
}
self.seasons = seasons
}
}
let json = """
{ "seasons": ["winter", "spring", "summer", "fall"] }
""".data(using: .utf8)!
let climate = try! JSONDecoder().decode(Climate.self, from: json)
However, the above code will result in an infinite loop due to the implementation of UnkeyedDecodingContainer.currentIndex. This is because the currentIndex is not incremented unless a decode succeeds.
Attachment: Download
Additional Detail from JIRA
md5: 8e5158944f566da394566f3054ff764a
Issue Description:
In the current implementation of Decodable, it is impossible to attempt to decode an array of Decodable's and allow individual items to fail.
For example:
This will raise an error of the following:
It may be considered desirable in certain use cases that this decode succeeds, but omits individual items that fail. As such, the desired output value would be:
One may attempt to circumvent this by using an outer, wrapper type combined with a customized initializer that ignores inner decode errors, such as the following:
However, the above code will result in an infinite loop due to the implementation of
UnkeyedDecodingContainer.currentIndex. This is because thecurrentIndexis not incremented unless a decode succeeds.