Skip to content

Instantly share code, notes, and snippets.

@zackdotcomputer
Created September 28, 2020 13:19
Show Gist options
  • Save zackdotcomputer/81b8545e3ce81128a299996814823963 to your computer and use it in GitHub Desktop.
Save zackdotcomputer/81b8545e3ce81128a299996814823963 to your computer and use it in GitHub Desktop.
Graceful Decoding for Swift Decodable
//
// Decodable+Graceful.swift
// Graceful Decodable
//
// Created by Zack Sheppard on 9/10/20.
// Copyright © 2020 Zack Sheppard. All rights reserved.
// Available under the MIT License
// Available at https://gist.github.com/zackdotcomputer/81b8545e3ce81128a299996814823963
//
import Foundation
// From https://medium.com/flawless-app-stories/how-to-safely-decode-arrays-using-decodable-result-type-in-swift-5b975ea11ff5
// A safe wrapper for rescuable decodable lists
public struct GracefulDecodable<T: Decodable>: Decodable {
public let result: Result<T, Error>
public init(from decoder: Decoder) throws {
let catching = { try T(from: decoder) }
result = Result(catching: catching )
}
}
extension KeyedDecodingContainer {
/// Try to decode a list of objects of a Decodable type, gracefully omitting those that fail to decode rather than failing the entire list.
func decodeGracefulList<OfType: Decodable>(_ type: OfType.Type, forKey key: KeyedDecodingContainer<K>.Key) throws -> [OfType] {
let values = try self.decode([GracefulDecodable<OfType>].self, forKey: key)
return values.compactMap({ $0.result.value })
}
/// Try to decode a list of objects of a Decodable type if present, gracefully omitting those that fail to decode rather than failing the entire list.
func decodeGracefulListIfPresent<OfType: Decodable>(_ type: OfType.Type, forKey key: KeyedDecodingContainer<K>.Key) throws -> [OfType]? {
let values = try self.decodeIfPresent([GracefulDecodable<OfType>].self, forKey: key)
return values?.compactMap({ $0.result.value })
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment