Skip to content

Instantly share code, notes, and snippets.

@osteslag
Created March 13, 2019 08:34
Show Gist options
  • Save osteslag/5fa2b2b61a0e38917a5c2d80f32e7cb4 to your computer and use it in GitHub Desktop.
Save osteslag/5fa2b2b61a0e38917a5c2d80f32e7cb4 to your computer and use it in GitHub Desktop.
Contrived example illustrating problems with singleValueContainer on Encoder, and maybe Character not being Codable.
// Contrived example illustrating problems with singleValueContainer on Encoder, and maybe Character not being Codable.
import XCTest
enum Suit: Character {
case diamonds = "♦"
case clubs = "♣"
case hearts = "♥"
case spades = "♠"
}
extension Suit: Codable { // Character isn't Codable
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(String(self.rawValue)) // Encode as String
}
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let character = try container.decode(String.self).first!
self.init(rawValue: character)!
}
}
let diamonds = Suit.diamonds
let encoder = JSONEncoder()
let encoded = try encoder.encode(diamonds)
// Playground execution terminated: An error was thrown and was not caught:
// ▿ EncodingError
// ▿ invalidValue : 2 elements
// - .0 : __lldb_expr_27.Suit.diamonds
// ▿ .1 : Context
// - codingPath : 0 elements
// - debugDescription : "Top-level Suit encoded as string JSON fragment."
// - underlyingError : nil
let decoder = JSONDecoder()
let decoded = try decoder.decode(Suit.self, from: encoded)
XCTAssertEqual(decoded, diamonds)
@osteslag
Copy link
Author

What’s the recommended way of working with singleValueContainer without wrapping in struct or Array, or using keying etc? See thread on Twitter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment