当你收到通知时,有几个函数可能会被调用,具体取决于应用的状态(前台、后台或终止)以及用户如何与通知交互。以下是这些函数及其触发条件:
1. userNotificationCenter(_:willPresent:withCompletionHandler:)
触发条件:当应用在前台运行并且接收到本地或远程通知时。
用途:允许应用决定如何处理通知(例如,显示横幅、播放声音等)。
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
// 处理通知
print("Will present notification: \(notification)")
// 决定如何显示通知
completionHandler([.alert, .sound])
}
2. userNotificationCenter(_:didReceive:withCompletionHandler:)
触发条件:当用户点击通知时(无论应用是在前台、后台还是已终止)。
用途:处理用户与通知的交互,例如打开特定的视图控制器或执行某些操作。
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
// 处理用户点击通知后的逻辑
let userInfo = response.notification.request.content.userInfo
print(“Received notification: \(userInfo)”)
// 完成处理
completionHandler()
}
3. application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
触发条件:当应用在后台运行并且接收到远程推送通知时。
用途:允许应用在后台处理通知数据,并决定是否唤醒应用以更新内容。
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// 处理远程通知
print(“Received remote notification: \(userInfo)”)
// 完成处理
completionHandler(.newData)
}
4. scene(_:willConnectTo:options:) 和 scene(_:continue:)
触发条件:在使用场景(Scene)委托的情况下,当应用从后台恢复或通过通知启动时。
用途:处理应用的启动和恢复逻辑。
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let notification = connectionOptions.notificationResponse?.notification.request.content.userInfo {
print(“Received notification in scene: \(notification)”)
}
}
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
if userActivity.activityType == NSUserActivityTypeBrowsingWeb, let url = userActivity.webpageURL {
print(“Continuing activity with URL: \(url)”)
}
}
执行函数条件
如果应用在前台:userNotificationCenter(_:willPresent:withCompletionHandler:) 是必执行的。
如果用户点击了通知:userNotificationCenter(_:didReceive:withCompletionHandler:) 是必执行的。
如果应用在后台:application(_:didReceiveRemoteNotification:fetchCompletionHandler:) 可能会被调用,但这不是必须的,因为系统不会总是唤醒应用来处理后台通知。
确保正确设置委托
确保你在 AppDelegate 或 SceneDelegate 中正确设置了 UNUserNotificationCenter 的委托,并且实现了上述方法。
import UserNotifications
import UIKit
@main
struct YourApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// 请求通知权限
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
if granted {
print(“Notification permission granted.”)
} else {
print(“Notification permission denied.”)
}
}
// 设置通知中心的委托
UNUserNotificationCenter.current().delegate = self
return true
}
// 处理应用从后台唤醒的情况
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// 处理远程通知
print(“Received remote notification: \(userInfo)”)
completionHandler(.newData)
}
// 实现 UNUserNotificationCenterDelegate 方法
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
// 当应用在前台时处理通知
completionHandler([.alert, .sound])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
// 处理用户点击通知后的逻辑 ,注意这个函数不是自动触发的,需要用户点击一下通知才会触发
let userInfo = response.notification.request.content.userInfo
print(“Received notification: \(userInfo)”)
// 完成处理
completionHandler()
}
}
通过以上设置,你可以确保在不同情况下都能正确处理通知。如果你仍然遇到问题,请检查日志输出,确保所有必要的代码都已实现并且没有其他配置问题。