You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xcode 11升级至Xcode 13后点击通知时Notification Delegates未被调用问题

解决方案:Xcode 13升级后通知代理未触发的问题

核心原因

iOS 13+ 引入了Scene生命周期,系统默认会将通知相关的回调分发到SceneDelegate,但你的项目基于旧版Xcode创建(无SceneDelegate),导致回调找不到接收方,所以代理方法没被调用。


方法一:移除Scene配置,回归纯AppDelegate生命周期

这是最直接的适配方式,适合不想引入SceneDelegate的项目:

  • 打开项目的Info.plist文件,找到并删除UIApplicationSceneManifest整个字典项(这是Scene模式的核心配置)
  • 确保AppDelegate中正确配置通知代理,并且在启动时就完成设置:
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // 请求通知权限
        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
            if let error = error {
                print("通知权限请求失败:\(error.localizedDescription)")
            }
        }
        // 关键:将通知代理绑定到AppDelegate
        center.delegate = self
        // 注册远程通知(如果使用APNs)
        application.registerForRemoteNotifications()
        return true
    }
    
  • 让AppDelegate遵循UNUserNotificationCenterDelegate协议,并实现点击通知的核心回调:
    extension AppDelegate: UNUserNotificationCenterDelegate {
        // 前台收到通知时的回调
        func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
            completionHandler([.alert, .sound, .badge])
        }
        
        // 点击通知后的核心回调(重点!)
        func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
            // 这里处理点击通知后的业务逻辑
            print("用户点击了通知:\(response.notification.request.content.userInfo)")
            completionHandler()
        }
        
        // 远程通知到达时的回调(可选)
        func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
            print("收到远程通知:\(userInfo)")
            completionHandler(.newData)
        }
    }
    

方法二:保留Scene配置,添加SceneDelegate处理通知

如果你的项目需要适配多窗口等Scene特性,可以添加SceneDelegate来接管通知回调:

  • 创建新的SceneDelegate.swift文件,实现基础配置和通知代理:
    import UIKit
    
    class SceneDelegate: UIResponder, UIWindowSceneDelegate {
        var window: UIWindow?
    
        func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
            guard let _ = (scene as? UIWindowScene) else { return }
            // 将通知代理绑定到SceneDelegate
            UNUserNotificationCenter.current().delegate = self
        }
    }
    
    extension SceneDelegate: UNUserNotificationCenterDelegate {
        // 前台收到通知
        func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
            completionHandler([.alert, .sound, .badge])
        }
        
        // 点击通知
        func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
            print("用户点击通知:\(response.notification.request.content.userInfo)")
            completionHandler()
        }
    }
    
  • 在Info.plist的UIApplicationSceneManifest -> UISceneConfigurations -> Default Configuration中,确保UISceneDelegateClassName的值设置为$(PRODUCT_MODULE_NAME).SceneDelegate(自动关联你的SceneDelegate类)

额外检查项

  • 确认用户已授权通知权限:可以在系统设置→你的App→通知中查看是否开启了允许通知
  • 测试远程通知时,确保推送payload包含alert字段(否则通知不会展示),后台推送需添加content-available: 1
  • 确保通知代理的设置时机足够早:必须在启动阶段完成绑定,不能延迟到后续页面加载时设置

内容的提问来源于stack exchange,提问作者Krishna Yadav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 18:17:44