SwiftyUserDefaults icon indicating copy to clipboard operation
SwiftyUserDefaults copied to clipboard

iCloud sync support

Open StevenSorial opened this issue 5 years ago • 8 comments

Have you thought of adding ICloud support via NSUbiquitousKeyValueStore?

I think it's a very reasonable feature to include and would fit well with the Swifty part of this library given that the native API is not very intuitive.

if yes, would you be open to a PR? :)

StevenSorial avatar Jan 30 '20 18:01 StevenSorial

Hey @StevenMagdy, yes I did! This is something I would really like to have - if it's possible to have with how we structured the API nowadays. Would be really awesome if you'd like to open a PR 🙌

sunshinejr avatar Jan 30 '20 18:01 sunshinejr

Great :)

if it's possible to have with how we structured the API nowadays.

That's actually was going to be my next question 😄 - is it even possible or not? and what's your advice to implement such a feature?

StevenSorial avatar Jan 30 '20 19:01 StevenSorial

@StevenMagdy not sure as I never used the cloud-kit backend for User Defaults, but I quickly looked at the API and:

  • It seems like UserDefaults are not connected with NSUbiquitousKeyValueStore with any protocol/class, but I think it could be easily replaced by a protocol e.g. KeyValueStore that would specify all the getters/setters
  • Now in version 5 we introduced DefaultsAdapter that should make the transition from UserDefaults to a KeyValueStore pretty straight-forward - probably replacing all the occurences of the UserDefaults type to the new protocol & then the global Defaults variable would use UserDefaults.standard as a provider as it is currently (and people that choose to use the cloud-kit backing could just override it)

please remember that this is just pure speculation as I didn't touch the code but you can always ping me here or in the PR with questions and I'll try to help as soon as possible :)

sunshinejr avatar Jan 30 '20 19:01 sunshinejr

the global Defaults variable would use UserDefaults.standard as a provider as it is currently (and people that choose to use the cloud-kit backing could just override it)

@sunshinejr actually I was thinking of making it per key:

extension DefaultsKeys {
    var launchCount: DefaultsKey<Int> { return .init("launchCount", defaultValue: 0, synced: true) }
}

or better:

extension DefaultsKeys {
    var launchCount: DefaultsSyncedKey<Int> { return .init("launchCount", defaultValue: 0) }
}

StevenSorial avatar Jan 30 '20 20:01 StevenSorial

@StevenMagdy ah interesting! So do you have more use-cases when you store only a few defaults, rather than the whole suite?

sunshinejr avatar Jan 30 '20 20:01 sunshinejr

actually no, but I'm sure it will be needed by others because the whole synced container has a 1 MB limit, so some users will have to keep larger keys local.

MKiCloudSync uses the same approach but in a less static way

StevenSorial avatar Jan 30 '20 20:01 StevenSorial

I worked with both UserDefaults and UbiquitousKeyValueStore and they both are indeed quite the same and I have many times thought to open PR myself, so +1.

The only real difference is that iCloud defaults can change behind your back from another device, which is a pretty common case that needs to be handled nicely via API.

For example, with traditional UserDefaults, you start the app, read preferences and configure UI. With iCloud, you start the app, register observers, start the app, and fresh iCloud defaults modified on another device arrive several seconds later and you need to reconfigure the app.

This would require augmenting the existing API to add some kind of notification closures to the whole defaults suite or to each preference individually.

Just my .2 euro cents, Martin

mman avatar Jan 31 '20 08:01 mman

@mman ah this explains the code behind MKiCloudSync 😄 yeah, this seems a little bit tougher now!

sunshinejr avatar Jan 31 '20 10:01 sunshinejr