IOS/Objective-C:点击本地通知跳转至APP指定页面
嘿,我来帮你搞定这个本地通知跳转特定页面的问题!其实不用纠结NSURL,咱们用更简单灵活的方式就能实现,一步步来:
第一步:发送本地通知时携带自定义页面标识
当你创建本地通知(比如用UNMutableNotificationContent)的时候,不用硬套NSURL,直接在userInfo字典里存一个自定义的页面标识就行——比如要跳转到订单详情页,就存个明确的键值对,还能顺便传参数(比如订单ID):
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; content.title = @"新订单提醒"; content.body = @"你有一笔新订单待处理"; // 这里存页面标识和需要的参数,键名可以自己定义,比如targetPage、orderID content.userInfo = @{ @"targetPage": @"OrderDetailViewController", @"orderID": @"123456" }; // 配置触发条件和通知请求,正常流程就行 UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5 repeats:NO]; UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"newOrder" content:content trigger:trigger]; [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:nil];
第二步:在
applicationDidBecomeActive:里处理跳转逻辑 在这个方法里,你需要先判断用户是不是通过点击通知激活的APP,然后解析userInfo里的标识,再跳转到对应页面。注意要避免重复处理同一条通知:
- (void)applicationDidBecomeActive:(UIApplication *)application { [super applicationDidBecomeActive:application]; UNUserNotificationCenter *notificationCenter = [UNUserNotificationCenter currentNotificationCenter]; // 获取已送达的通知列表,取最新的那条(用户刚点击的就是这条) [notificationCenter getDeliveredNotificationsWithCompletionHandler:^(NSArray<UNNotification *> * _Nonnull notifications) { if (notifications.count == 0) return; UNNotification *latestNotification = notifications.lastObject; NSDictionary *userInfo = latestNotification.request.content.userInfo; NSString *targetPage = userInfo[@"targetPage"]; // 根据标识跳转对应页面 if ([targetPage isEqualToString:@"OrderDetailViewController"]) { // 获取当前窗口的根控制器,这里假设根控制器是导航控制器 UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow; UINavigationController *rootNav = (UINavigationController *)keyWindow.rootViewController; // 实例化目标页面,顺便传参数 OrderDetailViewController *orderVC = [[OrderDetailViewController alloc] init]; orderVC.orderID = userInfo[@"orderID"]; // 跳转前可以检查导航栈里有没有这个页面,避免重复push BOOL hasExist = NO; for (UIViewController *vc in rootNav.viewControllers) { if ([vc isKindOfClass:[OrderDetailViewController class]]) { hasExist = YES; [rootNav popToViewController:vc animated:YES]; break; } } if (!hasExist) { [rootNav pushViewController:orderVC animated:YES]; } // 处理完后移除这条通知,防止下次激活APP重复处理 [notificationCenter removeDeliveredNotificationsWithIdentifiers:@[latestNotification.request.identifier]]; } }]; }
额外注意事项
- 如果你的APP是iOS 13及以后的版本,用了
SceneDelegate,那除了AppDelegate的方法,还要在sceneDidBecomeActive:里做同样的处理,因为现在APP可能有多个场景会话。 - 不用执着于NSURL,自定义
userInfo的方式更灵活,不仅能指定页面,还能传递各种业务参数,比解析URL方便太多。 - 跳转页面时记得适配你的APP的路由结构,如果用了自定义路由框架,直接调用路由跳转就行,不用手动实例化控制器。
内容的提问来源于stack exchange,提问作者user6631314




