If I use the default UserDefaults I can subscribe to changes via keypath to specific changes. However, if I use a UserDefaults instance created with the init(suiteName:), no changes are delivered.
According to the MAC Os release notes, the problem was fixed a while ago. However, I cannot confirm this. Does anyone know the problem and possibly a solution for it?
In previous releases, KVO could only be used on the instance of NSUserDefaults returned by the +standardUserDefaults method. Additionally, changes from other processes (such as defaults(1), extensions, or other apps in an app group) were ignored by KVO. These limitations have both been corrected. Changes from other processes will be delivered asynchronously on the main queue, and ignore NSKeyValueObservingOptionPrior.
Code Example:
import UIKit
import Combine
import Foundation
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
let provider = CalendarProvider()
}
extension UserDefaults {
@objc dynamic var startOfTheWeek: Int {
return integer(forKey: "startOfTheWeek")
}
}
final class CalendarProvider: ObservableObject {
@Published var currentCalendar: Calendar = Calendar.current
private var observer: NSKeyValueObservation?
init() {
var calendar = Calendar(identifier: .gregorian)
calendar.firstWeekday = 1
self.currentCalendar = calendar
observer = UserDefaults(suiteName: "group.foo.com")?
.observe(\.startOfTheWeek, options: [.new , .initial],
changeHandler: { (defaults, change) in
DispatchQueue.main.async {
var calendar = Calendar(identifier: .gregorian)
calendar.firstWeekday = change.newValue ?? 1
self.currentCalendar = calendar
}
})
DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: {
UserDefaults(suiteName: "group.foo.com")?.setValue(8, forKey: "startOfTheWeek")
})
}
deinit {
observer?.invalidate()
}
}