ios 应用未运行时推送通知单击处理程序

Posted

技术标签:

【中文标题】ios 应用未运行时推送通知单击处理程序【英文标题】:ios Push notification click handler when the app is not running 【发布时间】:2015-06-08 05:12:12 【问题描述】:

我运行以下代码来处理推送通知 -

我收到通知 -> 点击它 -> 然后执行 jsCallBack -> 将自定义数据作为参数传递给 JS 函数。

但这仅在应用程序在后台或前台运行时才有效。

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo 
    //Handle notification when the user click it while app is running in background or foreground.
    [[Pushbots sharedInstance] receivedPush:userInfo];
    //Get Custom field data
    NSString* Value1 = [userInfo objectForKey:@"customval1"];
    NSString* Value2 = [userInfo objectForKey:@"customval1"];
    NSLog(@"%@", Value1);
    NSLog(@"%@", Value2);

    NSString * jsCallBack = [NSString stringWithFormat:@"testfromdelegate('%@','%@')", Value1, Value2];
    NSLog(@"%@", jsCallBack);
    [self.viewController.webView stringByEvaluatingjavascriptFromString:jsCallBack];

我在 SO 和其他一些博客中阅读了 didFinishLaunchingWithOptions 的帖子,这些帖子可以帮助我在应用程序根本没有运行时处理通知。 This link has info 但不确定我的场景的实现。

请有人帮助我了解如何在我的情况下使用didFinishLaunchingWithOptions?我所需要的只是获取自定义数据字段,即使在应用程序未运行时也将它们传递给我的 JSCallBack。

我应该在我的 delegate.m 中同时包含 didReceiveRemoteNotificationdidFinishLaunchingWithOptions 吗?另外,当我还在 delegate.m 中使用 didFinishLaunchingWithOptions 时,我应该在 delegate.h 中进行哪些更改?

更新 1: 我了解到,当应用程序终止时,无法访问有效负载。而且,当应用程序处于前台或后台时,didReceiveRemoteNotification 在有推送通知时起作用。 但是,当我收到通知并在应用程序处于后台时点击它时,我无法调用我的 JS 回调函数。 我需要一些有关如何处理此问题的帮助。

【问题讨论】:

【参考方案1】:

您需要在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions中执行以下代码

NSDictionary *userInfo = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
if (userInfo) 
    [self application:application didReceiveRemoteNotification:userInfo];

【讨论】:

谢谢阿米特...这有帮助。但是当我从通知中心启动我的应用程序时(并且应用程序在后台),它总是会didReceiveRemoteNotification;它从不调用 didFinishLaunchingWithOptions。只有当我通过点击设备应用列表中的应用图标来启动应用时,才会调用“didFinishLaunchingWithOptions”。 是的,来自后台状态 didFinishLaunchingWithOptions 不调用。我建议的代码是“如果应用程序处于未运行状态并且有任何通知出现”JS callback 是另一回事。与您的webviewjs functionany hybrid framework if you using any 相关【参考方案2】:

首先,我认为您无法访问应用未运行时发出的所有通知。您只能访问您单击以激活应用程序的通知。我认为这里的这个帖子很好地解释了它

didReceiveRemoteNotification when in background

对于您的情况,我认为您需要以某种方式将计数器保持在服务器端,当应用程序处于活动状态时,然后交换它并检索应用程序错过的计数器。

现在,当应用程序启动时处理您的情况的代码,您可以在 didFinishLaunchingWithOptions 中执行此操作,我认为您需要保留现有函数 didReceiveRemoteNotification,因为当应用程序启动时收到通知时会调用它们在后台运行(未终止)

- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 

    UILocalNotification *localNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
    if (localNotif) 
    
        NSDictionary *userInfo;
        NSString* Value1 = [userInfo objectForKey:@"customval1"];
        NSString* Value2 = [userInfo objectForKey:@"customval1"];
        NSLog(@"%@", Value1);
        NSLog(@"%@", Value2);
        NSString * jsCallBack = [NSString stringWithFormat:@"testfromdelegate('%@','%@')", Value1, Value2];
        NSLog(@"%@", jsCallBack);
        [self.viewController.webView stringByEvaluatingJavaScriptFromString:jsCallBack];
        NSString *itemName = [localNotif.userInfo objectForKey:ToDoItemKey];
        [viewController displayItem:itemName];  // custom method
        NSString * jsCallBack = [NSString stringWithFormat:@"testfromdelegate('%@','%@')", Value1, Value2];
        NSLog(@"%@", jsCallBack);
        [self.viewController.webView stringByEvaluatingJavaScriptFromString:jsCallBack];    
    
   return YES;

【讨论】:

感谢您的回复。 "leave didReceiveRemoteNotification" .. 也就是说,它也应该在那里?我是 Objective-C 的新手,所以请帮助我理解 viewController displayItem:itemName??它抛出一个错误 所以当你收到远程通知didReceiveRemoteNotification 被调用。如果它根本没有运行并且在用户单击您的通知后启动了应用程序,您必须在didFinishLaunchingWithOptions 中处理它 知道了。做了一些实验并将 didFinishLaunchingWithOptions 添加到我的代码中。在我这样做之后,该应用程序根本没有启动。另外,我添加了 - “(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;”给我的委托人.h 哦,我的代码中错过了返回 YES 行,请更新它,您不需要将其添加到标题中 运气不好。只有当应用程序在前台运行时,我才能访问回调函数。当应用程序在后台运行时,我无法访问有效负载。此外,使用 didFinishLaunchingWIthOptions 根本不会启动我的应用程序。请帮忙。【参考方案3】:

这对我有用,正如 我的问题 + 更新-

中所要求的

如果应用程序在前台或后台 -

//app is in background/foreground
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo 

    [[Pushbots sharedInstance] receivedPush:userInfo]; //Using Pushbots notification platform - a 3rd party push platform

    NSString* Value1 = [userInfo objectForKey:@"val1"];
            NSString* Value2 = [userInfo objectForKey:@"val2"];
            NSString * jsCallBack = [NSString stringWithFormat:@"testfromdelegate('%@','%@')", Value1, Value2];            

    // If the app is in the foreground just execute the javascript        
    if ( application.applicationState == UIApplicationStateActive ) 
        [self.viewController.webView stringByEvaluatingJavaScriptFromString: jsCallBack];
     else 
    // If the app is in background, then force to execute the js code on the main thread
        [self.viewController.webView performSelectorOnMainThread:@selector(stringByEvaluatingJavaScriptFromString:) withObject:jsCallBack waitUntilDone:NO]
    

如果应用处于关闭状态, 将此添加到didFinishLaunchingWithOptions

//Don't remove the existing code, just paste this before the return YES
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(cordovaDidLoad) name:CDVPageDidLoadNotification object:self.viewController.webView];

    if (launchOptions)  //check if launchOptions is not nil
        NSDictionary *userInfo = [launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
        self.myUserInfo = userInfo;
    

并添加这个,将在 Cordova 加载后调用 -

- (void)cordovaDidLoad 
    //Check that myUserInfo isn't null, that will mean that the app was completely closed and it was opened from the push notification

    if (self.myUserInfo) 
        NSString* Value1 = [self.myUserInfo objectForKey:@"val1"];
        NSString* Value2 = [self.myUserInfo objectForKey:@"val2"];
        NSString * jsCallBack = [NSString stringWithFormat:@"testfromdelegate('%@','%@')", Value1, Value2];
        NSLog(@"%@", jsCallBack);
        [self.viewController.webView stringByEvaluatingJavaScriptFromString: jsCallBack];
    

【讨论】:

以上是关于ios 应用未运行时推送通知单击处理程序的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin.iOS 应用程序未运行时未处理 Amazon SNS 推送通知

IOS。处理推送通知而不是应用程序未运行

单击推送通知时对特定活动的意图。

IOS;当应用程序未运行或在后台时,推送通知不起作用

重定向以查看 IOS 通知栏中的点击推送消息

在 iOS 上单击时,Phonegap 插件推送通知保留在托盘中