Post

Replies

Boosts

Views

Activity

Reply to Correct loop for threaded UserDefaults.standard.addObserver observeValue
Thank you for your reply. the standard way to be notified for appearance changes is by use KVO to observe the effectiveAppearance property. I am fine with that, I was not 100% sure AppKit would have worked from a Swift command-line script, that's why I started with AppleInterfaceStyle. But, switching the observable would not really solve the problem at the core of this post. I would still need something to support continuous observation of any KVO from a background thread. Perhaps the whole approach is wrong: how would you implement a command line script (and, eventually, a library) that monitors such change on the system without blocking the main thread?
Topic: App & System Services SubTopic: General Tags:
Jul ’22
Reply to Correct loop for threaded UserDefaults.standard.addObserver observeValue
Since I am quite inexperienced in Swift/Foundation and since there is a doubt about the actual use case, I feel attaching a MWE of what I intend to do is probably beneficial. import Foundation let key = "AppleInterfaceStyle" class Observer: NSObject { override init() { super.init() UserDefaults.standard.addObserver(self, forKeyPath: key, options: [NSKeyValueObservingOptions.new], context: Optional<UnsafeMutableRawPointer>.none) } deinit { UserDefaults.standard.removeObserver(self, forKeyPath: key, context: Optional<UnsafeMutableRawPointer>.none) } override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { let result = change?[.newKey] ?? "" var theme : String = String(describing: result) if (theme == "<null>") { theme = "Light" } print("swift: detected \(theme)") } } public func main() -> Void { // Begin observing standardUserDefaults. let observer = Observer() _ = observer // silence "constant never used" warning RunLoop.current.run() } //main() //run from main thread with stdin // run from background DispatchQueue.global(qos: .background).async { main() } When running in this version, the script returns immediately. Uncommenting the direct call to main() results in the script functioning properly and printing to the stdout whenever the Appearance of the system is changed from System Preferences.
Topic: App & System Services SubTopic: General Tags:
Jul ’22
Reply to Correct loop for threaded UserDefaults.standard.addObserver observeValue
I’m confused by your requirements here. The idea of the library is to continuously observe AppleInterfaceStyle to run the callback if a user switches the Appearance of their system from Dark to Light or vice versa. In general KVO observers run on the thread that makes the change.  I was not aware of this. When I run my code from the Python main thread, or as a standalone CLI script, the monitoring works well even if the key change is obviously coming from System Preferences, and therefore not from the same thread.
Topic: App & System Services SubTopic: General Tags:
Jul ’22