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

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

相关推荐
jiushiapwojdap13 小时前
Flutter上手记:为什么我的按钮能同时在iOS和Android上跳舞?[特殊字符][特殊字符]
android·其他·flutter·ios
yede18 小时前
uniapp - 配置iOS的Universal Links
ios·uni-app
Andy_GF18 小时前
鸿蒙Next在蒲公英平台分发测试包
android·ios·harmonyos
zkmall21 小时前
ZKmall开源商城多端兼容实践:鸿蒙、iOS、安卓全平台适配的技术路径
ios·开源·harmonyos
东坡肘子1 天前
未来将至:人形机器人运动会 | 肘子的 Swift 周报 #099
swiftui·swift·apple
海的天空16611 天前
Flutter旧版本升级-> Android 配置、iOS配置
android·flutter·ios
kymjs张涛2 天前
零一开源|前沿技术周刊 #13
ios·harmonyos·apple
源码哥_博纳软云2 天前
JAVA国际版多商户运营版商城系统源码多商户社交电商系统源码支持Android+IOS+H5
android·java·ios·微信·微信小程序·小程序·uni-app
2501_915106322 天前
iOS混淆工具实战 金融支付类 App 的安全防护与合规落地
android·ios·小程序·https·uni-app·iphone·webview
I烟雨云渊T2 天前
iOS 数据持久化
macos·ios·cocoa