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

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

相关推荐
疯狂的程序猴6 小时前
Flutter应用代码混淆完整指南:Android与iOS平台配置详解
后端·ios
SY.ZHOU7 小时前
移动端架构体系(五):终篇总结
flutter·ios·系统架构·安卓·鸿蒙
Digitally12 小时前
如何不用 iTunes 将 iPhone 备份到移动硬盘?
ios·iphone
sysinside12 小时前
Cisco Catalyst 9000 IOS XE 26.1.1 GA - 思科 Catalyst 9000 交换产品系列 IOS XE 系统软件
ios·cisco
低保和光头哪个先来12 小时前
解决 ios 使用 video 全屏未铺满页面问题
前端·javascript·vue.js·ios·前端框架
报错小能手13 小时前
SwiftUI 框架 认识 SwiftUI 视图结构 + 布局
ui·ios·swift
2501_9159214313 小时前
HTTP和HTTPS协议全面解析:技术原理与安全应用
安全·http·ios·小程序·https·uni-app·iphone
悟空爬虫-彪哥13 小时前
VRCFaceTracking安装和iPhone面捕配置教程,有bug
ios·bug·iphone
想个名字想老半天13 小时前
uni离线打包实现 ios 支付StoreKit 2,其实没有想象中那么复杂,不需要写原生插件,不需要转 uts
macos·ios·cocoa
东坡肘子14 小时前
被 Vibe 摧毁的版权壁垒,与开发者的新护城河 -- 肘子的 Swift 周报 #131
人工智能·swiftui·swift