Skip to content

Return UserDefaults dictionaryRepresentation double values as doubles#67

Merged
marcprux merged 1 commit intoskiptools:mainfrom
dfabulich:userdefaults-doubles
Jun 4, 2025
Merged

Return UserDefaults dictionaryRepresentation double values as doubles#67
marcprux merged 1 commit intoskiptools:mainfrom
dfabulich:userdefaults-doubles

Conversation

@dfabulich
Copy link
Contributor

@dfabulich dfabulich commented Jun 3, 2025

Fixes #54

This implementation adds a "sidecar" property __unrepresentableType when you set a value that's unrepresentable in SharedPreferences. (We do not set a sidecar property when the type is representable, to avoid waste.)

Note that this implementation no longer sets floats as Int via Float.toRawBits(), because SharedPreferences supports Float values natively; the tests verify that we can store arbitrary precision floats. (The tests also verify that floats that were saved as Int bits can be restored, guaranteeing backwards compatibility.)

We're also now no longer adding prefix strings for the types stored as strings: Data, Date, and URL. But, again, the backwards compatibility tests ensure that values stored before this change can still be deserialized as expected.

Skip Pull Request Checklist:

  • REQUIRED: I have signed the Contributor Agreement
  • REQUIRED: I have tested my change locally with swift test
  • OPTIONAL: I have tested my change on an iOS simulator or device
  • OPTIONAL: I have tested my change on an Android emulator or device

@cla-bot cla-bot bot added the cla-signed label Jun 3, 2025
@marcprux
Copy link
Member

marcprux commented Jun 3, 2025

Thanks very much for this! But I had been hoping for a solution more in line with the description at #54, where each stored property has a "sidecar" property with the expected type. That would allow us to disambiguate not only between Long/Double and Int/Float values, but also Date/Data/URL/String without doing any additional parsing, as well as opening the door to possibly support array defaults.

This would be a bit more of an overhaul than a quick fix, so I can take it on in the next couple days if you like. But if you want to tackle it, please go ahead.

@dfabulich dfabulich force-pushed the userdefaults-doubles branch from 3dc34e3 to 672d2f9 Compare June 3, 2025 20:13
Copy link
Member

@marcprux marcprux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking great! In addition to the couple of nits, could you also ensure that when a default is removed or nil'd that it also removes the __unrepresentable__ sidecar value if it exists?

@dfabulich dfabulich force-pushed the userdefaults-doubles branch from 672d2f9 to aa512c7 Compare June 4, 2025 05:33
@marcprux
Copy link
Member

marcprux commented Jun 4, 2025

Looks great, thanks!

@marcprux marcprux merged commit 9f16fec into skiptools:main Jun 4, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UserDefaults dictionaryRepresentation returns Double values as Int64/Long

2 participants