收到推送通知时推送视图控制器 iOS

Posted

技术标签:

【中文标题】收到推送通知时推送视图控制器 iOS【英文标题】:Push View Controller When Push Notification Received iOS 【发布时间】:2015-09-08 19:19:25 【问题描述】:

我有一个使用 XIB 而不是 Storyboard 的应用。 rootViewController 是一个 TabBarController。有 5 个选项卡,每个选项卡都包含一个 NavigationController。我想做的是让应用程序在用户点击收到的推送通知时推送某个视图控制器。在我的 didFinishLaunchingWithOptions 中(除其他设置外):

 window.rootViewController = self.tabBarController;
    [window makeKeyAndVisible];

在后面的代码中:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo 
    [PFPush handlePush:userInfo];
    if (application.applicationState == UIApplicationStateInactive) 
        [self handleRemoteNotificationWithPayload:userInfo];
    

-(void)handleRemoteNotificationWithPayload:(NSDictionary *)payload 
   NSLog(@"User tapped notification");
    NewsViewController *dvController8 = [[NewsViewController alloc] initWithNibName:@"NewsViewController" bundle:[NSBundle mainBundle]];
        [self.tabBarController.navigationController pushViewController:dvController8 animated:YES];



但是,当我点击通知时,什么都没有发生,尽管 NSLog 确实在控制台中触发。有什么建议吗?

根据答案,我现在有

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo 
    [PFPush handlePush:userInfo];
    UINavigationController *nav = (UINavigationController *) self.tabBarController.selectedViewController;
    NewsViewController *dvController8 = [[NewsViewController alloc] initWithNibName:@"NewsViewController" bundle:[NSBundle mainBundle]];
    [nav pushViewController:dvController8 animated:YES];


但这只有在应用程序已经在后台暂停运行时才有效。如果它已经崩溃或用户从应用切换器强制关闭它,它只会打开应用,而不是推动控制器。

编辑:

这里是didFinishLaunchingWithOptions 方法:

UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert |
                                                    UIUserNotificationTypeBadge |
                                                    UIUserNotificationTypeSound);



    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes
                                                                             categories:nil];

    [[UIApplication sharedApplication]
     registerUserNotificationSettings:settings];
    [application registerUserNotificationSettings:settings];
    [application registerForRemoteNotifications];

【问题讨论】:

【参考方案1】:

如果标签控制器上的每个标签都是导航控制器,请尝试以下操作:

UINavigationController *nav = (UINavigationController *) self.tabBarController.selectedViewController;
NewsViewController *dvController8 = [[NewsViewController alloc] initWithNibName:@"NewsViewController" bundle:[NSBundle mainBundle]];
[nav pushViewController:dvController8 animated:YES];

所以基本上首先获取所选控制器的引用,然后在所选视图控制器上创建一个pushViewController。

编辑,如果应用不在后台运行时如何处理:

如果应用程序未在后台运行,则必须在 application:didFinishLaunchingWithOptions 上执行此操作

文档说:“如果应用程序在远程通知到达时未运行,则该方法会启动应用程序并在启动选项字典中提供适当的信息。应用程序不会调用此方法来处理该远程通知。而是,您的 application:willFinishLaunchingWithOptions: 或 application:didFinishLaunchingWithOptions: 方法的实现需要获取远程通知负载数据并做出适当的响应。”

请查收:https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/#//apple_ref/occ/intfm/UIApplicationDelegate/application:didReceiveRemoteNotification:

所以我的建议是首先创建一个辅助方法来处理您的通知,如下所示:

- (void)handleNotification:(NSDictionary *)userInfo 
    UINavigationController *nav = (UINavigationController *) self.tabBarController.selectedViewController;
    NewsViewController *dvController8 = [[NewsViewController alloc] initWithNibName:@"NewsViewController" bundle:[NSBundle mainBundle]];
    [nav pushViewController:dvController8 animated:YES];

从现在开始,每次你需要处理远程通知时,你只需要调用 handleNotification 方法。

第二次将您的 didReceiveRemoteNotification 实现更改为:

[self handleNotification:userInfo];

最后将以下内容添加到您的 didFinishLaunchingWithOptions 实现中:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
    // your code here


    if ([launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]) 
        // this means we received a remote notification
        [self handleNotification:(NSDictionary *) [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]];
    

    return YES;

所以在 didFinishLaunchingWithOptions 方法中检查 launchOptions 字典是否有为 UIApplicationLaunchOptionsRemoteNotificationKey 分配的对象。如果是这样,则意味着该应用程序是从远程通知中打开的。分配给该键的值是通知的有效负载。

注意:我没有在 xcode 上测试代码,所以可能有一些拼写错误,但您应该了解如何实现您需要的。

希望对你有帮助!

【讨论】:

好的,我改变了它,它按预期打开了 NewsViewController,但有一个小问题。每次在强制关闭后打开应用程序时都会执行此操作(不仅仅是在后台暂停),而不仅仅是在单击通知时。是什么原因造成的? 对为什么这样做有任何想法吗? 如果我将[self handleRemoteNotificationWithPayload:userInfo]; 放在didFinishLaunchingWithOptions 方法中,控制器会在每次首次打开应用程序时被推送,而不仅仅是在收到通知时。你能看到 OP 编辑​​当前如何显示该方法并帮助指导我吗?

以上是关于收到推送通知时推送视图控制器 iOS的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin/Mvvmcross:收到 iOS 推送通知时打开不同的视图控制器

iOS - 收到推送通知后显示视图

收到多个推送通知时应用程序冻结

当用户使用 iOS 13 Swift 5 点击推送通知时,在特定视图中打开应用程序

iOS - 在收到推送通知事件时更改视图的内容

收到推送通知时显示视图控制器不起作用,其视图不在窗口层次结构中