You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

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

火山引擎 最新活动