点击本地推送通知时如何跳转至指定页面?iOS星座APP问题
解决iOS本地推送点击后跳转指定页面而非首页的问题
问题根源排查
- 未设置通知中心代理:若未在
AppDelegate的启动方法中绑定代理,通知回调不会触发,系统默认打开首页。 - 页面跳转逻辑错误:直接替换
rootViewController的方式,在APP已启动(后台/前台)场景下可能失效,还会破坏原有导航结构。 - 标识匹配问题:需确认Storyboard中目标控制器的ID为
deneme,且类名与代码中的detailView完全一致(建议Swift类名首字母大写,改为DetailView避免潜在问题)。
修正后的代码实现
1. 完善AppDelegate的通知代理绑定
在AppDelegate的启动方法中添加代理设置:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 其他初始化代码 UNUserNotificationCenter.current().delegate = self return true }
2. 优化通知点击回调逻辑
区分APP状态,采用更稳妥的跳转方式:
extension AppDelegate: 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) { guard response.notification.request.identifier == "asd" else { completionHandler() return } let storyboard = UIStoryboard(name: "Main", bundle: nil) guard let targetVC = storyboard.instantiateViewController(withIdentifier: "deneme") as? DetailView else { completionHandler() return } // 根据APP当前状态处理跳转 if let rootVC = self.window?.rootViewController { if let navVC = rootVC as? UINavigationController { // 根控制器是导航控制器时,直接push目标页面 navVC.pushViewController(targetVC, animated: true) } else { // 否则以present方式打开 rootVC.present(targetVC, animated: true) } } else { // APP未启动时,将目标页面设为根控制器(可嵌套导航控制器) self.window?.rootViewController = UINavigationController(rootViewController: targetVC) self.window?.makeKeyAndVisible() } completionHandler() } }
3. 修正本地推送代码的拼写错误
func checkPermission() { let notificationCenter = UNUserNotificationCenter.current() notificationCenter.getNotificationSettings { settings in switch settings.authorizationStatus { case .authorized: self.dispatchNotification() case .denied: return case .notDetermined: notificationCenter.requestAuthorization(options: [.alert, .sound]) { didAllow, error in if didAllow { self.dispatchNotification() } } default: return } } } func dispatchNotification() { let identifier = "asd" let userNotification = UNUserNotificationCenter.current() let content = UNMutableNotificationContent() content.title = "Hu huu" content.body = "Yeni Geldi Yorumlar..." content.sound = .default let hour = 22 let minute = 29 let isDaily = true let calendar = Calendar.current var dateComponent = DateComponents(calendar: calendar, timeZone: TimeZone.current) dateComponent.hour = hour dateComponent.minute = minute let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponent, repeats: isDaily) let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger) userNotification.removePendingNotificationRequests(withIdentifiers: [identifier]) userNotification.add(request) }
额外注意事项
- 确认Storyboard中目标控制器的Storyboard ID为
deneme,类名与代码中的DetailView完全匹配(注意大小写)。 - 若APP使用iOS 13+的
SceneDelegate,需在SceneDelegate中同步处理通知回调逻辑,或确保AppDelegate的window设置正常。 - 测试时需覆盖APP后台、完全关闭两种状态,验证跳转效果。
内容的提问来源于stack exchange,提问作者yusuf kutlay
相关产品推荐
相关产品推荐

