Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PostMessage Bridge activation inconsistent btw platforms #13006

Closed
dotnetprofessional opened this issue Mar 17, 2017 · 3 comments
Closed

PostMessage Bridge activation inconsistent btw platforms #13006

dotnetprofessional opened this issue Mar 17, 2017 · 3 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@dotnetprofessional
Copy link

Description

The Android and iOS platforms differ in the order in which they setup the linkBridge. The iOS version sets the bridge up first then executes user supplied scripts. However, Android does this in the reverse order. The iOS order is preferred and considered to be the correct order. This has caused an issue with our application in that we want to override the postMessage of the bridge, but out code executes prior to the bridge being configured, which means we have to resort to a hack of setting a setTimeout. This is not necessary with the iOS version.

Android implementation:

    public void onPageFinished(WebView webView, String url) {
      super.onPageFinished(webView, url);

      if (!mLastLoadFailed) {
        ReactWebView reactWebView = (ReactWebView) webView;
        reactWebView.callInjectedJavaScript();
        reactWebView.linkBridge();
        emitFinishEvent(webView, url);
      }
    }

iOS

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
  if (_messagingEnabled) {
    #if RCT_DEV
    // See isNative in lodash
    NSString *testPostMessageNative = @"String(window.postMessage) === String(Object.hasOwnProperty).replace('hasOwnProperty', 'postMessage')";
    BOOL postMessageIsNative = [
      [webView stringByEvaluatingJavaScriptFromString:testPostMessageNative]
      isEqualToString:@"true"
    ];
    if (!postMessageIsNative) {
      RCTLogError(@"Setting onMessage on a WebView overrides existing values of window.postMessage, but a previous value was defined");
    }
    #endif
    NSString *source = [NSString stringWithFormat:
      @"window.originalPostMessage = window.postMessage;"
      "window.postMessage = function(data) {"
        "window.location = '%@://%@?' + encodeURIComponent(String(data));"
      "};", RCTJSNavigationScheme, RCTJSPostMessageHost
    ];
    [webView stringByEvaluatingJavaScriptFromString:source];
  }
  if (_injectedJavaScript != nil) {
    NSString *jsEvaluationValue = [webView stringByEvaluatingJavaScriptFromString:_injectedJavaScript];

    NSMutableDictionary<NSString *, id> *event = [self baseEvent];
    event[@"jsEvaluationValue"] = jsEvaluationValue;

    _onLoadingFinish(event);
  }
  // we only need the final 'finishLoad' call so only fire the event when we're actually done loading.
  else if (_onLoadingFinish && !webView.loading && ![webView.request.URL.absoluteString isEqualToString:@"about:blank"]) {
    _onLoadingFinish([self baseEvent]);
  }
}

Solution

Swap these two lines in the Android version:

        reactWebView.callInjectedJavaScript();
        reactWebView.linkBridge();

to be this:

        reactWebView.linkBridge();
        reactWebView.callInjectedJavaScript();

Additional Information

  • React Native version: 0.42.0
  • Operating System: Android
@hramos
Copy link
Contributor

hramos commented May 25, 2017

We're cutting down on the number of outstanding issues, in order to allow us to focus. I'm closing this issue because it has been open for over 60 days with no activity. If you think it should still be opened let us know why. PRs are always welcome.

@hramos hramos closed this as completed May 25, 2017
@hramos hramos added the Icebox label May 26, 2017
@getaaron
Copy link
Contributor

getaaron commented Feb 9, 2018

@dotnetprofessional do you know if this was ever resolved?

@dotnetprofessional
Copy link
Author

This does not seem to have been resolved. Its a quick fix for anyone who has the environment setup. In our case we ended up with a fully custom WebView for Android and iOS. As such this fix isn't important to us, but I believe it is still important! Here's the offending code:

@facebook facebook locked as resolved and limited conversation to collaborators May 29, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

4 participants