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 入口或视图中按需请求。

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

相关推荐
Funny Valentine-js16 小时前
swift菜鸟教程29-30(泛型,访问控制)
开发语言·ios·swift
明远湖之鱼18 小时前
在H5页面的SSR中,客户端需要做哪些工作?
ios
闫良呀18 小时前
Swift + SwiftUI原生iOS开发 开发笔记3 – 自主模型部署并获取识别结果
ios·swiftui
声知视界19 小时前
音视频基础能力之 iOS 视频篇(六):使用Metal进行视频渲染
ios·音视频开发
18538162800余。1 天前
碰一碰发视频源码开发深度解析,定制化开发
macos·objective-c·cocoa
returnShitBoy1 天前
iOS 上的内存管理是如何处理的?
macos·ios·cocoa
opentogether1 天前
PODS_ROOT、BUILT_PRODUCTS_DIR和SRCROOT有什么区别
ios
90后的晨仔2 天前
Socket 与 WebSocket 的区别是啥?
ios
林晨月2 天前
SwiftUI 国际化
ios
Funny Valentine-js2 天前
swift菜鸟教程1-5(语法,变量,类型,常量,字面量)
开发语言·ios·swift