我正在构建一个 macOS 应用程序。
我希望能够通过更新名为
showAtLaunch
的 UserDefaults 键来触发应用程序启动到不同模式
应用程序运行时我让它观察
showAtlaunch
let observer = UserDefaults.standard.observe(\.showAtLaunch, options: .new) { (foo, change) in
// DO SOMETHING
}
问题是,当应用程序运行时,我从终端运行以下命令
defaults write ~/Library/Preferences/com.myMacOS.App.plist showAtLaunch 1
它会更新 plist 文件,但不会在应用程序中触发。
如果我使用以下代码:
UserDefaults.standard.addObserver(self, forKeyPath: "showAtLaunch", options: .new, context: nil)
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?,
context: UnsafeMutableRawPointer?) {
print("""
in observeValue keyPath: \(String(describing: keyPath))
value: \(UserDefaults.standard.integer(forKey: "showAtLaunch"))
""")
}
Block based KVO
因此我想使用新的 API 来观察事物。
对此的任何帮助或见解都会很棒!
您需要保留(消失)通过调用
observe(:options:)
获得的返回类型,因为当它被破坏时,您的观察者将停止工作。所以如果你只这样做
let observer = UserDefaults.standard.observe(\.showAtLaunch, options: .new) { (foo, change) in
// DO SOMETHING
}
在函数内部,一旦函数完成,观察就会结束。
因此,向类型添加一个属性,该属性将在您的应用程序的整个生命周期中存在,或者只要您需要像主应用程序一样观察
一个 SwiftUI 示例
@main
struct MyApp: App {
var defaultsObserver: NSKeyValueObservation
//...
}
然后分配给
init
中的属性,或者将其设为可选,如果 init
不合适,稍后再执行。