Mirroring feature
I just implemented a today widget in one of my apps. I needed to read a preference item in the today widget that was currently stored in my main app. Usually, this would mean having to migrate the key over to the App Groups user defaults suite. However, I'm lazy and instead just went with observing the key and then setting it in the App Groups user defaults suite when changed:
// Constants.swift
extension Defaults.Keys {
static let timeZonesInMenu = Key<[ChosenTimeZone]>("timeZonesInMenu", default: [])
}
// SharedConstants.swift
struct Constants {
static let appGroupId = "XXXX.com.sindresorhus.Dato.shared"
static let sharedDefaults = UserDefaults(suiteName: appGroupId)!
}
extension Defaults.Keys {
static let sharedTimeZones = Key<[ChosenTimeZone]>("sharedTimeZones", default: [], suite: Constants.sharedDefaults)
}
// OtherFile.swift
// Sync time zone changes to the shared item.
Defaults.observe(.timeZonesInMenu) { change in
Defaults[.sharedTimeZones] = change.newValue
}
.tieToLifetime(of: self)
And I was thinking this might be useful for others too.
I'm thinking:
// Key with same name
Defaults.mirror(.key, to: suite)
// Key with different name (where the key is strongly-typed and defined in a shared Constants.swift file or something)
Defaults.mirror(.key, to: suite, as: .sharedKey)
// Key with different name
Defaults.mirror(.key, to: suite, as: "sharedKey")
Would probably need a similar unmirror method too.
Note that this is not syncing. It's only one way.
Feedback welcome.
I wonder why it would be right to encourage such use. Setting up an app group is really easy, just a few clicks in Xcode
I haven't needed this since, so probably not worth it.