iOS应用未运行时点击推送通知无响应如何调试与解决?
调试方案
- 修改Xcode运行配置即可实现冷启动推送场景的断点调试:打开Xcode顶部菜单
Product > Scheme > Edit Scheme,在Run选项的Info标签页中,把「Launch」选项从「Automatically」改为「Wait for the executable to be launched」。配置完成后运行项目,Xcode会等待你手动点击推送通知启动App,调试器不会断开,可以直接打断点查看launchOptions中的参数。
功能不生效的排查&修复
你的逻辑不生效大概率是两个原因:一是跳转时机过早,二是如果用了SceneDelegate没有对应适配,修复步骤如下:
- 不要在
didFinishLaunchingWithOptions中直接执行跳转逻辑,此时App的根控制器、页面栈还没有完成初始化,直接触发跳转必然失效。你需要先把冷启动收到的通知payload存储到全局临时变量,等App页面完全加载完成后再处理跳转。
// 全局定义临时存储变量,可放在AppDelegate或自定义全局存储类中 var coldLaunchNotificationPayload: [AnyHashable: Any]?
// didFinishLaunching中仅做存储,不做跳转 func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { // 其他初始化逻辑 if let remoteNotif = launchOptions?[.remoteNotification] as? [AnyHashable: Any] { coldLaunchNotificationPayload = remoteNotif } return true }
- 适配SceneDelegate场景:如果你的项目适配iOS13及以上,且使用了SceneDelegate管理窗口,冷启动的通知参数需要在SceneDelegate的
willConnectTo方法中获取:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { if let remoteNotif = connectionOptions.notificationResponse?.notification.request.content.userInfo { coldLaunchNotificationPayload = remoteNotif } }
- 延迟处理跳转逻辑:在根控制器的
viewDidAppear回调或者App进入活跃状态的applicationDidBecomeActive回调中,判断是否有冷启动存储的通知payload,存在的话复用你之前在didReceive回调中的跳转逻辑处理即可,处理完成后把临时变量置空避免重复跳转:
func applicationDidBecomeActive(_ application: UIApplication) { guard let payload = coldLaunchNotificationPayload else { return } // 复用你之前写的跳转逻辑 jumpToTargetPage(payload: payload) // 处理完成后置空 coldLaunchNotificationPayload = nil }
弹窗不生效的原因
你用DispatchQueue.main.asyncAfter(deadline: .now() + 5)延时5秒弹窗,此时如果App还没有完成页面初始化,windows.first?.rootViewController可能还没有赋值,或者没有完成控制器栈的加载,找不到最上层的控制器,弹窗自然无法弹出,按上述调试方案直接断点查看参数即可,不需要用弹窗排查。
内容的提问来源于stack exchange,提问作者Tariq
相关产品推荐
相关产品推荐

