3.1 在 AppDelegate 或 SwiftUI Lifecycle 中配置权限请求

在 SwiftUI 中请求用户通知权限,可以通过两种方式实现:

  1. 传统方式 :基于 AppDelegate(兼容 UIKit 项目)

  2. 纯 SwiftUI 方式 :使用 @main 入口和 SwiftUI 生命周期(iOS 14+)

以下分别说明两种方法的具体实现。


方法 1:通过 AppDelegate 请求权限

适用于混合 UIKit/SwiftUI 项目或需要兼容旧版本 iOS 的情况。

步骤 1:创建 AppDelegate 类

swift

复制

复制代码
import UIKit
import UserNotifications

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        
        // 请求通知权限
        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
            if granted {
                print("通知权限已授权")
            } else if let error = error {
                print("权限请求失败:\(error.localizedDescription)")
            }
        }
        
        return true
    }
}
步骤 2:在 SwiftUI 入口绑定 AppDelegate

swift

复制

复制代码
import SwiftUI

@main
struct MyApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

方法 2:纯 SwiftUI 生命周期请求权限

适用于 iOS 14+ 的纯 SwiftUI 项目,无需 AppDelegate

步骤 1:在 App 入口初始化时请求权限

swift

复制

复制代码
import SwiftUI
import UserNotifications

@main
struct MyApp: App {
    init() {
        requestNotificationPermission()
    }
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
    
    // 请求权限的私有方法
    private func requestNotificationPermission() {
        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
            if granted {
                print("通知权限已授权")
            } else if let error = error {
                print("权限请求失败:\(error.localizedDescription)")
            }
        }
    }
}
步骤 2(可选):在视图中动态请求权限

如果希望根据用户操作(如点击按钮)请求权限:

swift

复制

复制代码
struct ContentView: View {
    @State private var isPermissionGranted = false
    
    var body: some View {
        VStack {
            Button("请求通知权限") {
                requestNotificationPermission()
            }
        }
    }
    
    private func requestNotificationPermission() {
        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, _ in
            DispatchQueue.main.async {
                isPermissionGranted = granted
            }
        }
    }
}

注意事项

  1. 请求时机

    • 避免在应用启动时立即请求权限(可能降低用户体验)。

    • 推荐在用户执行相关操作后请求(例如首次打开"提醒"功能时)。

  2. 处理权限拒绝

    • 若用户拒绝权限,可引导用户前往系统设置手动开启:

    swift

    复制

    复制代码
    if let url = URL(string: UIApplication.openSettingsURLString) {
        UIApplication.shared.open(url)
    }
  3. 检查当前权限状态

    swift

    复制

    复制代码
    UNUserNotificationCenter.current().getNotificationSettings { settings in
        switch settings.authorizationStatus {
        case .authorized: print("已授权")
        case .denied: print("已拒绝")
        case .notDetermined: print("未决定")
        default: break
        }
    }

总结

  • 传统项目 :通过 AppDelegate 集中管理权限请求。

  • 纯 SwiftUI 项目 :在 @main 入口或视图中按需请求。

  • 最佳实践:根据用户上下文动态请求权限,提升用户体验。

相关推荐
CocoaKier8 小时前
推荐一个历代iPhone设备型号网站,比维基百科好用
ios·apple
笑尘pyrotechnic9 小时前
自动布局视图来实现聊天室的界面
ui·ios·objective-c
2501_9159090610 小时前
Charles中文版使用教程 高效抓包与API调试常见问题处理
android·ios·小程序·https·uni-app·iphone·webview
键盘敲没电14 小时前
【iOS】KVO
学习·macos·ios·objective-c·cocoa
00后程序员张14 小时前
iOS软件性能监控实战指南 开发到上线的完整流程解析
android·ios·小程序·https·uni-app·iphone·webview
杂雾无尘17 小时前
解密 Swift 5.5 中的 @MainActor, 深入了解其优势与误区
ios·swift·客户端
路过看风景17 小时前
zsh: command not found: pod
ios·cocoapods
吴Wu涛涛涛涛涛Tao17 小时前
SwiftUI 打造 TikTok 风格的滑动短视频播放器
ios·swiftui
小指纹18 小时前
河南萌新联赛2025第(三)场:河南理工大学【补题】
数据结构·c++·算法·macos·ios·objective-c·cocoa
呼啸长风1 天前
记一次未成功的 MMKV Pull Request
android·ios·开源