Skip to content

[iOS] WebView should handle custom URL scheme correctly #9037

Closed
@eggli

Description

@eggli

Hi, we're working on a small RN project which has an in-app browser embed inside, the product itself has been released on AppStore, but yet we have received some randomly error screen rendered in the WebView, after a long time investigation, we finally figured out it's the iOS deep linking URL scheme triggered the default WebView error render view, which can be easily reproduced via entering a SlideShare.net URL(not the mobile one), which redirects the WebView to it's own app, if user has no such app installed on their device, a WebKitErrorDomain will be throw from UIWebView hence triggers all the rest error handling mechanisms.

Here's the URL we are testing:

http://www.slideshare.net/branchmetrics/the-2016-mobile-growth-handbook-64218146

RNPlay to reproduce:
https://rnplay.org/apps/TxDHtw

RNPlay is still on 0.24, but this error can also be reproduced on RN 0.30.0

And here's the screenshot from XCode where the error has been thrown:

screen shot 2016-07-27 at 3 50 05 pm

As you can see, the error from UIWebView shows the NSErrorFailingURLKey as slideshare-app://ss/64093801 which is a custom URL scheme.

If we open the test link mentioned above in Safari.app without SlideShare app installed, Safari won't show any error message and working perfectly.

I've been searched the issues reported here, found these issue might be related to this error:
#6707, #7839, #4337, #7839.

Here's few thoughts to resolve this issue:

  1. WebView shouldn't trigger onLoadingError if the URL scheme itself is not supported, just like Safari.
  2. Currently, onLoadingError is going to render WebView's view state to error thus rendered the error view, default or not, it should allow developers to decide where to show error view or not via returning true/false after invoking onError method. In such case, the error event sent from RCTWebView to WebView should had the NSErrorFailingURLKey included, not only the url from UIWebView.

Activity

lacker

lacker commented on Oct 28, 2016

@lacker
Contributor

There is at least a workaround, from one of those other issues:

<WebView
  domStorageEnabled={ true }
  javaScriptEnabled={ true }
  renderError={ (e) => {
    if (e === 'WebKitErrorDomain') {
      return
    }
  }}
  source={{ uri: "https://99f9e623.ngrok.io/auth/sign_in_with_slack?source=app" }}
  style={ styles.container }
/>

The question which I don't know the answer to is whether this behavior is inherent to WebView and the right solution is switching to WKWebView (as some have suggested), or whether this can just be fixed in WebView.

messutied

messutied commented on Nov 4, 2016

@messutied

@lacker that workaround does not solve this issue for me :( it only hides the error message but the webview turns blank when it happens.

I'm testing in react-native 0.36.1.

alexkasemir

alexkasemir commented on Nov 17, 2016

@alexkasemir

yes @lacker, that workaround does not seem to work.

jjshammas

jjshammas commented on Dec 27, 2016

@jjshammas

Well an easy solution would be just to return NO for shouldStartLoadWithRequest if the protocol is not HTTP or HTTPS: https://github.com/facebook/react-native/blob/master/React/Views/RCTWebView.m#L251

Any idea what the repercussions might be if that were the case?

Alternatively, could add a property to WebView supporting an array of ignored protocols. For a quick and dirty solution until this is resolved I modified the above linked line as such to support Plaid Link:

if (!isJSNavigation) {
	BOOL isPlaidNavigation = [request.URL.scheme isEqualToString:@"plaidlink"];
	return !isPlaidNavigation;
}
return YES;

There also seems to be a shouldStartLoadWithRequest prop on the WebView RN component, but it is undocumented and I am not sure if it works completely.

indivisable

indivisable commented on Feb 4, 2017

@indivisable

@jjshammas Do you have working example for your RCTWebView? I am trying to get it to work with Plaid Link too with not much luck :/

firetheworld

firetheworld commented on May 20, 2017

@firetheworld

I'm on RN version 0.43,I have this problem too
Have you fixed this problem, please help?
@lacker @eggli

eggli

eggli commented on May 22, 2017

@eggli
Author

@firetheworld Yes, we did solve this problem by doing it in a super brutal and not-very-open-source-way: We wrote our own iOS WebView to replace React Native's built in since no one in Facebook cares about this problem and we found it's not easy to solve, here's our solution, it's brutal, not very cool, but it works:

- (BOOL)webView:(__unused UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
 navigationType:(UIWebViewNavigationType)navigationType
{
 
  if (![request.URL.scheme isEqual:@"http"] && 
      ![request.URL.scheme isEqual:@"https"] && 
      ![request.URL.scheme isEqual:@"about:blank"]) {
         if ([[UIApplication sharedApplication]canOpenURL:request.URL]) {
             [[UIApplication sharedApplication]openURL:request.URL];
         }
      return NO;
  }

return YES;

}

In the code above, if we found the URL is not whatever we can handle, we skip it to avoid any error message being throw to React Native, and asks iOS if user's device is capable to handle that custom scheme url, if so, we hand over the URL to iOS so user still get other apps' deep linking URL working.

I believe there SHOULD be a better way ( or at least a neat one ) to handle this.

hramos

hramos commented on Jul 26, 2017

@hramos
Contributor

Hi there! This issue is being closed because it has been inactive for a while. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. Either way, we're automatically closing issues after a period of inactivity. Please do not take it personally!

If you think this issue should definitely remain open, please let us know. The following information is helpful when it comes to determining if the issue should be re-opened:

  • Does the issue still reproduce on the latest release candidate? Post a comment with the version you tested.
  • If so, is there any information missing from the bug report? Post a comment with all the information required by the issue template.
  • Is there a pull request that addresses this issue? Post a comment with the PR number so we can follow up.

If you would like to work on a patch to fix the issue, contributions are very welcome! Read through the contribution guide, and feel free to hop into #react-native if you need help planning your contribution.

zsaraf

zsaraf commented on Nov 8, 2017

@zsaraf

Any update on whether this will be fixed in a future release? Still having the exact same issue

5 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @shergin@lacker@hramos@eggli@messutied

        Issue actions

          [iOS] WebView should handle custom URL scheme correctly · Issue #9037 · facebook/react-native