diff --git a/Tusker/LazilyDecoding.swift b/Tusker/LazilyDecoding.swift index c21ba79e..e96b4d7e 100644 --- a/Tusker/LazilyDecoding.swift +++ b/Tusker/LazilyDecoding.swift @@ -37,10 +37,10 @@ public struct LazilyDecoding { } else { guard let data = instance[keyPath: wrapper.keyPath] else { return wrapper.fallback } do { - let value = try decoder.decode(Value.self, from: data) - wrapper.value = value + let value = try decoder.decode(Box.self, from: data) + wrapper.value = value.value instance[keyPath: storageKeyPath] = wrapper - return value + return value.value } catch { return wrapper.fallback } @@ -50,7 +50,7 @@ public struct LazilyDecoding { var wrapper = instance[keyPath: storageKeyPath] wrapper.value = newValue instance[keyPath: storageKeyPath] = wrapper - let newData = try? encoder.encode(newValue) + let newData = try! encoder.encode(Box(value: newValue)) instance[keyPath: wrapper.keyPath] = newData } } @@ -62,3 +62,11 @@ extension LazilyDecoding { self.init(from: keyPath, fallback: [] as! Value) } } + +extension LazilyDecoding { + // PropertyListEncoder only allows top-level types to be dicts or arrays, which breaks encoding nil-able values. + // Wrapping everything in a Box ensures that it's always a dict. + private struct Box: Codable { + let value: T + } +}