You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI视图未随AppDelegate中变量变更更新的问题求助

问题分析与解决方案

核心问题

  1. 状态未被SwiftUI追踪:AppDelegate的@Published属性未被SwiftUI观察,状态变化无法触发视图刷新
  2. 逻辑判断颠倒:当前代码中权限已授权时显示NotificationView,与需求相反
  3. 授权后未主动更新状态:用户完成授权后,没有重新查询权限状态并更新变量
  4. 线程安全问题:异步权限查询的回调在后台线程,直接更新@Published属性可能导致UI异常

修改后的完整代码

1. AppDelegate.swift

class AppDelegate: NSObject, ObservableObject, UIApplicationDelegate, UNUserNotificationCenterDelegate {
    @Published var notificationStatus: Bool = false
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        UNUserNotificationCenter.current().delegate = self
        checkNotificationPermission()
        return true
    }
    
    // 封装权限检查逻辑,方便重复调用
    func checkNotificationPermission() {
        let center = UNUserNotificationCenter.current()
        center.getNotificationSettings { [weak self] settings in
            // 切换到主线程更新UI状态
            DispatchQueue.main.async {
                switch settings.authorizationStatus {
                case .authorized, .provisional:
                    self?.notificationStatus = true
                case .notDetermined, .denied, .ephemeral, @unknown default:
                    self?.notificationStatus = false
                }
            }
        }
    }
}

2. appApp.swift

@main
struct appApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    @ObservedObject private var delegate: AppDelegate { appDelegate }
    
    var body: some Scene {
        WindowGroup {
            // 修正逻辑:已授权显示ContentView,未授权显示NotificationView
            if delegate.notificationStatus {
                ContentView()
            } else {
                NotificationView(checkPermission: appDelegate.checkNotificationPermission)
            }
        }
    }
}

3. NotificationView.swift(示例)

struct NotificationView: View {
    let checkPermission: () -> Void
    
    var body: some View {
        VStack(spacing: 20) {
            Text("需要您的通知权限")
                .font(.title)
            
            Button("开启通知权限") {
                UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { _, _ in
                    // 授权完成后立即检查最新状态
                    self.checkPermission()
                }
            }
            .buttonStyle(.borderedProminent)
        }
        .padding()
    }
}

关键修改说明

  • 让AppDelegate继承ObservableObject:使@Published属性的变化能被SwiftUI感知
  • 封装权限检查方法:统一启动时和授权后的状态更新逻辑
  • 主线程更新状态:异步回调必须切换到主线程,避免UI更新异常
  • 使用@ObservedObject观察AppDelegate:确保状态变化时自动触发视图重绘
  • 授权后主动更新状态:在用户完成授权请求后,调用检查方法刷新状态,触发视图切换

内容的提问来源于stack exchange,提问作者Brandon Brunson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 13:07:16