我已经进行了大量搜索并阅读了一堆文章,但我无法让 SwiftUI 根据模型中不断变化的变量动态更新视图,至少我正在做的事情是这样的。基本上我想根据应用程序的UNNotificationSettings.UNAuthorizationStatus
. 我让应用程序在启动时检查状态并显示状态。如果未确定状态,则点击文本将触发请求通知对话框。但是,在用户允许或拒绝通知后,视图不会更新。我确定我错过了一些基本的东西,因为我已经尝试了十几种方法,包括 with @Published ObservableObject
, @ObservedObject
,@EnvironmentObject
等。
struct ContentView: View {
@EnvironmentObject var theViewModel : TestViewModel
var body: some View {
VStack {
Text(verbatim: "Notifications are: \(theViewModel.notificationSettings.authorizationStatus)")
.padding()
}
.onTapGesture {
if theViewModel.notificationSettings.authorizationStatus == .notDetermined {
theViewModel.requestNotificationPermissions()
}
}
}
}
class TestViewModel : ObservableObject {
@Published var notificationSettings : UNNotificationSettings
init() {
notificationSettings = type(of:self).getNotificationSettings()!
}
func requestNotificationPermissions() {
let permissionsToRequest : UNAuthorizationOptions = [.alert, .sound, .carPlay, .announcement, .badge]
UNUserNotificationCenter.current().requestAuthorization(options: permissionsToRequest) { granted, error in
if granted {
print("notification request GRANTED")
}
else {
print("notification request DENIED")
}
if let error = error {
print("Error requesting notifications:\n\(error)")
}
else {
DispatchQueue.main.sync {
self.notificationSettings = type(of:self).getNotificationSettings()!
}
}
}
}
static func getNotificationSettings() -> UNNotificationSettings? {
var settings : UNNotificationSettings?
let start = Date()
let semaphore = DispatchSemaphore(value: 0)
UNUserNotificationCenter.current().getNotificationSettings { notificationSettings in
settings = notificationSettings
semaphore.signal()
}
semaphore.wait()
while settings == nil {
let elapsed = start.distance(to: Date())
Thread.sleep(forTimeInterval: TimeInterval(0.001))
if elapsed > TimeInterval(1) {
print("ERROR: did not get notification settings in less than a second, giving up!")
break
}
}
if settings != nil {
print("\(Date()) Notifications are: \(settings!.authorizationStatus)")
}
return settings
}
}
func getUNAuthorizationStatusString(_ authStatus : UNAuthorizationStatus) -> String {
switch authStatus {
case .notDetermined: return "not determined"
case .denied: return "denied"
case .authorized: return "authorized"
case .provisional: return "provisional"
case .ephemeral: return "ephemeral"
@unknown default: return "unknown case with rawValue \(authStatus.rawValue)"
}
}
extension UNAuthorizationStatus : CustomStringConvertible {
public var description: String {
return getUNAuthorizationStatusString(self)
}
}
extension String.StringInterpolation {
mutating func appendInterpolation(_ authStatus: UNAuthorizationStatus) {
appendLiteral(getUNAuthorizationStatusString(authStatus))
}
}
编辑:我尝试添加 objectWillChange 但视图仍未更新。
class TestViewModel : ObservableObject {
let objectWillChange = ObservableObjectPublisher()
@Published var notificationSettings : UNNotificationSettings {
willSet {
objectWillChange.send()
}
}
init() {
notificationSettings = type(of:self).getNotificationSettings()!
}