SwiftUI通知权限被拒绝时Toggle未自动关闭问题排查
问题排查与修复
核心问题分析
你的代码存在两个关键问题导致Toggle无法自动关闭:
权限请求回调未覆盖所有场景
NotificationManager的requestNotificationPermissions方法仅在授权成功或发生错误时调用completion,但用户手动拒绝授权时(success=false且error=nil),没有任何分支处理,导致后续的reminderEnabled=false逻辑根本不会执行。视图中重复持有Observable引用
AppSettingsView同时绑定了game和appSettings两个@Bindable实例,可能造成状态同步异常,视图无法感知到appSettings的变化。
修复方案
1. 修复NotificationManager的权限请求逻辑
确保所有授权场景都触发completion回调:
final class NotificationManager { static let shared = NotificationManager() var deniedAlertShown: Bool = false private init() {} func requestNotificationPermissions(completion: @escaping(Bool) -> Void) { UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { success, error in if let error { print("error requesting permissions: \(error.localizedDescription)") } // 无论成功、拒绝还是错误,都返回授权状态 completion(success) } } func cancelNotification() { UNUserNotificationCenter.current().removeAllPendingNotificationRequests() } }
2. 简化AppSettingsView的状态绑定
去掉多余的appSettings参数,直接通过game访问子属性,保证状态同步:
struct AppSettingsView: View { @Bindable var game: Game var body: some View { NavigationStack { VStack { Form { Toggle("Daily Reminder", isOn: $game.appSettings.reminderEnabled) .onChange(of: game.appSettings.reminderEnabled) { newValue in if newValue { NotificationManager.shared.requestNotificationPermissions { granted in DispatchQueue.main.async { if granted { NotificationManager.shared.scheduleNotification(at: game.appSettings.reminderTime) } else { game.appSettings.reminderEnabled = false } } } } else { NotificationManager.shared.cancelNotification() } } } } } } }
3. 优化AppSettings的持久化逻辑(可选)
用@AppStorage替代手动操作UserDefaults,简化代码并避免潜在错误:
@Observable final class AppSettings { @AppStorage(UserDefaultKeys.reminderEnabled) var reminderEnabled: Bool = false // 无需手动实现init和didSet,@AppStorage自动处理持久化 }
验证逻辑
修复后,当用户打开Toggle触发权限请求:
- 若用户点击“允许”:保持Toggle开启,执行通知调度逻辑
- 若用户点击“不允许”:completion会收到
granted=false,在主线程将reminderEnabled设为false,视图会通过@Bindable感知到变化,自动关闭Toggle
内容的提问来源于stack exchange,提问作者Jeevan Daniel Mahtani
相关产品推荐
相关产品推荐

