From 0249207dcc1bb4bebae47b35c55975558c2a993c Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Wed, 11 Nov 2020 12:44:57 -0500 Subject: [PATCH] Fix LazilyDecoding not handling top-level optionals --- Tusker/LazilyDecoding.swift | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Tusker/LazilyDecoding.swift b/Tusker/LazilyDecoding.swift index c21ba79ea2..e96b4d7e1f 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 + } +}