didReceiveRemoteNotification 中的 stringByEvaluatingJavaScriptFromString 但在加载 webView 之后

stringByEvaluatingJavaScriptFromString in didReceiveRemoteNotification but after webView is loaded

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

  1. 用户在应用程序处于后台时收到推送通知 -> 点击通知中心的通知 -> 应用程序打开(调用) -> 获取自定义负载值 -> 使用 [=11= 执行 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 还没有准备好,因为应用程序是从后台调用的。

  1. 我该怎么做才能完成这项工作?如何检查我的 webView 是否准备好,然后执行我的 jsCallBack?
  2. 当应用程序根本不是 运行 时,我该如何执行此操作?例如,用户收到一条 Whatsapp 消息,但该应用不在 background/foreground 中。但是,当用户点击来自通知中心的消息时,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];
    }

}