Created
April 27, 2018 16:28
-
-
Save khanlou/290889d0e558240ee07f2f919fc25541 to your computer and use it in GitHub Desktop.
via @irace
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
/** | |
Decode an array of objects while simply omitting any nested objects that themselves fail to be decoded. | |
Inspired by https://stackoverflow.com/a/46369152/503916 | |
*/ | |
struct SafeDecodableArray<T: Decodable>: Decodable { | |
/* | |
An intermediate type that always succeeds at being decoded. Necessary because when iterating the | |
`unkeyedContainer` below, all calls to `decode` must succeed (or the container's current index won't be | |
incremented and we'll never reach the end. | |
*/ | |
private struct SafeDecodable<T: Decodable>: Decodable { | |
let underlying: T? | |
init(from decoder: Decoder) throws { | |
let container = try decoder.singleValueContainer() | |
// Just store `nil` if we can't decode this | |
self.underlying = try? container.decode(T.self) | |
} | |
} | |
let objects: [T] | |
init(from decoder: Decoder) throws { | |
var undecoded = try decoder.unkeyedContainer() | |
var decoded: [T] = [] | |
while !undecoded.isAtEnd { | |
if let underlying = try undecoded.decode(SafeDecodable<T>.self).underlying { | |
decoded.append(underlying) | |
} | |
/* | |
Unfortunately, I don't think we have the underlying data available here, so we don't really have | |
anything to log when decoding fails. | |
*/ | |
} | |
self.objects = decoded | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment