如何观察 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
更新文本:
which updates text based on a String
from Station.status
:
class Station: ObservableObject {
@Published var status: String = UserDefaults.standard.string(forKey: "status") ?? "OFFLINE" {
didSet {
UserDefaults.standard.set(status, forKey: "status")
}
}
但是,我需要在我的 AppDelegate
中更改 status
的值,因为那是我收到我的 Firebase 云消息:
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 测试版.
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屋!