Created
October 24, 2018 19:57
-
-
Save SlaunchaMan/1cba8f9ba210a04895b25a73e08df1df to your computer and use it in GitHub Desktop.
Decoding items when one of them may not decode successfully.
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
extension KeyedDecodingContainer { | |
/// An item that cannot be decoded. Used in `compactDecode(arrayOf:forKey:)` | |
/// to represent items that could not be decoded. | |
private struct UndecodableItem: Decodable {} | |
/// Attempts to decode an array of type `T`. If an individual item in the | |
/// array fails to decode, these errors are not passed on to the caller; | |
/// instead, they are not included in the final array. | |
/// | |
/// - Parameters: | |
/// - type: The type to decode. | |
/// - key: The key to decode into an array of type `T`. | |
/// - Returns: An array of type `[T]` containing all of the successfully- | |
/// decoded items. | |
/// - Throws: This method will only throw errors that occur outside of | |
/// decoding individual items; for instance, if the item at `key` | |
/// is not an array. | |
func compactDecode<T: Decodable>(arrayOf type: T.Type, | |
forKey key: K) throws -> [T] { | |
guard contains(key) else { return [] } | |
var container = try self.nestedUnkeyedContainer(forKey: key) | |
var decodedItems = [T]() | |
while !container.isAtEnd { | |
if let decodedItem = try? container.decode(type) { | |
decodedItems.append(decodedItem) | |
} else { | |
// To get the container to advance, it must decode *something*, | |
// so decode an empty struct. | |
_ = try container.decode(UndecodableItem.self) | |
} | |
} | |
return decodedItems | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment