Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@khanlou
Created April 27, 2018 16:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save khanlou/290889d0e558240ee07f2f919fc25541 to your computer and use it in GitHub Desktop.
Save khanlou/290889d0e558240ee07f2f919fc25541 to your computer and use it in GitHub Desktop.
via @irace
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