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

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

相关推荐
权咚5 小时前
阿权的开发经验小集
git·ios·xcode
用户095 小时前
TipKit与CloudKit同步完全指南
ios·swift
法的空间12 小时前
Flutter JsonToDart 支持 JsonSchema
android·flutter·ios
2501_9159184113 小时前
iOS 上架全流程指南 iOS 应用发布步骤、App Store 上架流程、uni-app 打包上传 ipa 与审核实战经验分享
android·ios·小程序·uni-app·cocoa·iphone·webview
00后程序员张14 小时前
iOS App 混淆与加固对比 源码混淆与ipa文件混淆的区别、iOS代码保护与应用安全场景最佳实践
android·安全·ios·小程序·uni-app·iphone·webview
东坡肘子15 小时前
完成 Liquid Glass 的适配了吗?| 肘子的 Swift 周报 #0102
swiftui·swift·apple
Magnetic_h1 天前
【iOS】设计模式复习
笔记·学习·ios·设计模式·objective-c·cocoa
00后程序员张1 天前
详细解析苹果iOS应用上架到App Store的完整步骤与指南
android·ios·小程序·https·uni-app·iphone·webview
前端小超超1 天前
capacitor配置ios应用图标不同尺寸
ios·蓝桥杯·cocoa
2501_915106321 天前
Xcode 上传 ipa 全流程详解 App Store 上架流程、uni-app 生成 ipa 文件上传与审核指南
android·macos·ios·小程序·uni-app·iphone·xcode