-
Notifications
You must be signed in to change notification settings - Fork 25.1k
Closed
Labels
Resolution: LockedThis issue was locked by the bot.This issue was locked by the bot.
Description
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
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Resolution: LockedThis issue was locked by the bot.This issue was locked by the bot.