我在Cordova混合应用程序的iOS推送通知中遇到问题,需要指导/帮助来确定我是否以正确的方式进行操作?
这是流程->

  • 当应用程序处于后台时,用户收到推送通知->从通知中心点击通知->应用程序被打开(调用)->获取自定义有效载荷值->使用stringByEvaluatingJavaScriptFromString执行JS回调-> JS函数将执行应用必须执行的必要操作。

  • 这是我正在执行的代码
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    
        [[Pushbots sharedInstance] receivedPush:userInfo]; //Using Pushbots notification platform
    
        NSString* Value1 = [userInfo objectForKey:@"val1"];
        NSString* Value2 = [userInfo objectForKey:@"val2"];
    
        NSString * jsCallBack = [NSString stringWithFormat:@"testfromdelegate('%@','%@')", Value1, Value2];
        NSLog(@"%@", jsCallBack);
        [self.viewController.webView stringByEvaluatingJavaScriptFromString:jsCallBack];
    }
    

    一切工作到我的NSLog(@"%@", jsCallBack);为止,并且在jsCallBack失败。我了解到调用我的jsCallBack时,由于该应用是从后台调用的,因此webView尚未就绪。
  • 我该怎么做才能使这项工作?如何检查我的webView是否准备就绪,然后执行我的jsCallBack?
  • 当应用程序完全不运行时,该怎么办?例如,用户收到了Whatsapp消息,而该应用程序不在后台/前景中。但是,当用户点击通知中心中的消息时,whatsapp应用会随用户聊天屏幕一起打开。

  • PS:当应用程序处于前台时,所有这些代码都可以完美运行。这意味着,webView已经存在,因此jsCallBack没问题。

    最佳答案

    如果应用处于打开状态或后台,则可以直接执行javascript:

    //This will be called if the app was open, in the foreground (active) or in the background and you reopen it from a push message
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    
        [[Pushbots sharedInstance] receivedPush:userInfo]; //Using Pushbots notification platform
    
        NSString* Value1 = [userInfo objectForKey:@"val1"];
                NSString* Value2 = [userInfo objectForKey:@"val2"];
                NSString * jsCallBack = [NSString stringWithFormat:@"testfromdelegate('%@','%@')", Value1, Value2];
                NSLog(@"%@", jsCallBack);
        // If the app is in the foreground just execute the javascript
        if ( application.applicationState == UIApplicationStateActive ) {
            [self.viewController.webView stringByEvaluatingJavaScriptFromString: jsCallBack];
        } else {
             // If the app was in background, then force to execute the js code on the main thread
            [self.viewController.webView performSelectorOnMainThread:@selector(stringByEvaluatingJavaScriptFromString:) withObject:jsCallBack waitUntilDone:NO]
        }
    
    }
    

    如果应用程序已完全关闭,则可以添加一个侦听器,该侦听器将侦听CDVPageDidLoadNotification(cordova完成加载),因此将userInfo存储在新变量myUserInfo中,然后等待页面加载以使用它:
    - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
    {
        //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];
        //This will be called if the app was closed completelly and you open it from a push
        if (launchOptions) { //launchOptions is not nil
            NSDictionary *userInfo = [launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
            self.myUserInfo = userInfo;
        }
    
        return YES;
    
    }
    

    然后,在加载cordova时,将调用此方法:
    - (void)cordovaDidLoad {
        //Check that myUserInfo isn't null, that will mean that the apps was completelly 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];
        }
    
    }
    

    10-07 23:22