sindresorhus / Defaults

💾 Swifty and modern UserDefaults
https://swiftpackageindex.com/sindresorhus/Defaults/documentation/defaults
MIT License
1.97k stars 117 forks source link

Issue with custom type #115

Closed mac-gallagher closed 1 year ago

mac-gallagher commented 1 year ago

Hi @sindresorhus + all 👋

I've been trying to write a custom type to encode/decode Dimension (superclass of the various measurement units e.g. UnitTemperature, UnitMass). In my bridge, I'm relying on the fact that a Dimension is uniquely defined by its symbol:

extension Dimension: DefaultsSerializable {
  public static let bridge = Defaults.DimensionBridge()
}

extension Defaults {

  public struct DimensionBridge: Bridge {

    public func serialize(_ dimension: Dimension?) -> String? {
      dimension?.symbol
    }

    public func deserialize(_ symbol: String?) -> Dimension? {
      if let symbol = symbol {
        return .init(symbol: symbol)
      }
      return nil
    }
  }
}
public static let massUnit = Key<UnitMass?>("massUnit") // example key

However, this is what I'm seeing in practice

print(Defaults[.massUnit]) // nil

Defaults[.massUnit] = .grams

print(Defaults[.massUnit]) // still nil!

If using a default value like

public static let massUnit = Key<UnitMass>("massUnit", default: .grams) // example key

this is what I see


print(Defaults[.massUnit]) // grams

Defaults[.massUnit] = .kilograms

print(Defaults[.massUnit]) // still grams!

Any idea what's going wrong here? I stepped through its breakpoints and my implementation seems to be working fine, but the Defaults don't seem to be getting updated? 🤔

Thanks for the help in advance! Mac

mac-gallagher commented 1 year ago

Another weird thing is that the Defaults.publisher gets triggered whenever I set a new value to massUnit, but the change property has the same unit for both newValue and oldValue


Defaults.publisher(.massUnit)
  .sink { change in
    print(change.oldValue) // grams
    print(change.newValue) // grams
}
mac-gallagher commented 1 year ago

Discovered the root cause! It was related to UserDefaults not immediately writing to disk, I wasn't aware there was a delay :)