IOS SWIFT开发系列–收到通知后有哪些函数可能被调用,什么情况下调用?

当你收到通知时,有几个函数可能会被调用,具体取决于应用的状态(前台、后台或终止)以及用户如何与通知交互。以下是这些函数及其触发条件:

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()
    }
}


通过以上设置,你可以确保在不同情况下都能正确处理通知。如果你仍然遇到问题,请检查日志输出,确保所有必要的代码都已实现并且没有其他配置问题。

IOS SWIFT开发系列–收到通知后有哪些函数可能被调用,什么情况下调用?

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Scroll to top