如何观察UserDefaults中的更改? [英] How to observe changes in UserDefaults?
问题描述
我的视图中有一个@ObservedObject
:
struct HomeView: View {
@ObservedObject var station = Station()
var body: some View {
Text(self.station.status)
}
会根据Station.status
中的String
更新文本:
class Station: ObservableObject {
@Published var status: String = UserDefaults.standard.string(forKey: "status") ?? "OFFLINE" {
didSet {
UserDefaults.standard.set(status, forKey: "status")
}
}
但是,我需要在AppDelegate
中更改status
的值,因为这是接收
However, I need to change the value of status
in my AppDelegate
, because that is where I receive my Firebase Cloud Messages:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// Print full message.
let rawType = userInfo["type"]
// CHANGE VALUE OF status HERE
}
但是如果我更改AppDelegate
中的status
UserDefaults
值-在我看来它不会更新.
But if I change the status
UserDefaults
value in AppDelegate
- it won't update in my view.
status
更改时如何通知我的@ObservedObject
?
How can my @ObservedObject
in my view be notified when status
changes?
忘记提及在上述示例中使用了SwiftUI的2.0 beta版.
Forgot to mention that the 2.0 beta version of SwiftUI is used in the said example.
推荐答案
这是可能的解决方法
import Combine
// define key for observing
extension UserDefaults {
@objc dynamic var status: String {
get { string(forKey: "status") ?? "OFFLINE" }
set { setValue(newValue, forKey: "status") }
}
}
class Station: ObservableObject {
@Published var status: String = UserDefaults.standard.status {
didSet {
UserDefaults.standard.status = status
}
}
private var cancelable: AnyCancellable?
init() {
cancelable = UserDefaults.standard.publisher(for: \.status)
.sink(receiveValue: { [weak self] newValue in
guard let self = self else { return }
if newValue != self.status { // avoid cycling !!
self.status = newValue
}
})
}
}
注意:SwiftUI 2.0 允许您通过AppStorage
直接在视图中使用/观察UserDefaults
,因此,如果仅在视图中需要该状态,则可以使用
Note: SwiftUI 2.0 allows you to use/observe UserDefaults
in view directly via AppStorage
, so if you need that status only in view, you can just use
struct SomeView: View {
@AppStorage("status") var status: String = "OFFLINE"
...
这篇关于如何观察UserDefaults中的更改?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!