Today I’ve released version 0.6 of Multiplatform Settings! I thought I’d write a few words about what’s been added and what’s still to come.
One major new feature is a Windows implementation which stores data in the registry. For that I’m thankful for the initial contribution from Andrew Mikhaylov, without which I wouldn’t have known how any of the Windows APIs work. It currently doesn’t implement the listener APIs in
ObservableSettings, but it should be possible to get something working in the future, using something like RegNotifyChangeKeyValue. Contributions welcome. If you do native Windows work, let me know if it meets your needs.
Another new feature is a new module called
multiplatform-settings-no-arg. This is in response to a longstanding friction I’ve heard of from some users, where configuration can seem too complicated. I’ve generally focused the design of Multiplatform Settings around platform interop, with the expectation that you probably have some existing key-value storage that you want to use from both your shared and platform-specific code. But if that doesn’t matter for your use-case, needing to configure things separately from each platform can be frustrating. So the no-arg module lets you call
Settings() from common code. Note that this is not currently implemented on Windows, but it is available for other existing platforms. More details in the readme
A minor update is the addition of
keys APIs, which have been a longstanding to-do item of mine. I held off for a while because they behave unintuitively on Apple platforms, where after a
clear() call some keys are still present. However, after realizing that this might already be confusing for the
hasKey() API that already exists, I decided that it wasn’t a reason to keep them out of the library.
Finally, this release brings better thread-safety for update listeners on Apple platforms. This is something I’ve been wanting to get back and improve for a long time, and is the biggest reason the listeners are still marked experimental. To avoid forcing all listeners to freeze, there’s a flag you can pass to
AppleSettings on creation. If
useFrozenListeners is false, you get the pre-existing behavior, where nothing gets frozen but you’ll get freeze exceptions if you update from a background thread and trigger a callback. If
useFrozenListeners is true, it is safe to update things from arbitrary threads, but the listener lambda will be frozen, so you must be sure not to accidentally capture mutable state. Try it out and let me know how it works for you! Thanks to Kevin Galligan for feedback on an early draft of the code.
A couple things I’ve had on the to-do list are still in-progress. I’ve done some prototyping of integrations with both kotlinx.coroutines and kotlinx.serialization. The coroutine branch I’ve chosen to hold off on for a little while longer to do some thinking about how to handle threading, but the pull-request is available if you’d like to manually add it to your own code. The serialization integration needs more work in order to avoid calling into internal APIs, and is missing some functionality like collections. I’ve also been doing some prototyping of a desktop Linux implementation using DBM-style APIs. I haven’t been able to get it working yet, but I’d also love to get some feedback on whether that’s actually a useful direction to go in for interop purposes, or if there’s something else better to use.
Also, as a bonus, I've also published version 0.6-1.4-M1. This is the same as 0.6, but built against the Kotlin 1.4-M1 preview release. Check it out if you like living in the future.