gree / unity-webview

zlib License
2.29k stars 691 forks source link

Adding Uri exclusion list for making some redirect URI to be considered as Universal Links #1111

Open b-phygtl opened 2 weeks ago

b-phygtl commented 2 weeks ago

Hello,

We have been using the Gree plugin for unity for both Android and iOS. One of the things we encountered is that our redirect URIs are Universal Links(iOS) / Deeplinks(Android). That means whenever we encounter such links we would like to have the Android/iOS to trigger an Intent/Activity respectively on each platform. Currently Gree plugin opens the redirect Uri on the webview itself and we'd like to have Gree create the Intent/Activity calls for platforms.

For that I have modified the plugin to provide an API where one could add an Uri to an exclusion list and whenever there is an Uri with Protocol://your.domainname.com/ comes in it'd call the deeplink in the phone.

I want to create a pull request for your review. I was wondering if you have any suggestion or recommendation to handle this scenario. Please let me know.

KojiNakamaru commented 2 weeks ago

Have you looked SetURLPattern()? #550 shows its brief usage.

b-phygtl commented 2 weeks ago

Yes, I had taken a look at this before.

I do have a question on that. If I add the redirect URI into the Deny pattern, does the Gree Webview creates an Intent or it gives a call back to the hooked function ? The reason I asked this is because the SetURLPattern() doesnt seem to create an Intent on Android(as well as in iOS) since the

public boolean shouldOverrideUrlLoading(WebView view, String url) { canGoBack = webView.canGoBack(); canGoForward = webView.canGoForward(); boolean pass = true; if (mAllowRegex != null && mAllowRegex.matcher(url).find()) { pass = true; } else if (mDenyRegex != null && mDenyRegex.matcher(url).find()) { pass = false; } if (!pass) { return true; } if (url.startsWith("unity:")) { String message = url.substring(6); mWebViewPlugin.call("CallFromJS", message); return true; } else if (mHookRegex != null && mHookRegex.matcher(url).find()) { mWebViewPlugin.call("CallOnHooked", url); return true; } else if (!url.toLowerCase().endsWith(".pdf") && !url.startsWith("https://maps.app.goo.gl") && (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("file://") || url.startsWith("javascript:"))) { mWebViewPlugin.call("CallOnStarted", url); // Let webview handle the URL return false; } Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); // PackageManager pm = a.getPackageManager(); // List apps = pm.queryIntentActivities(intent, 0); // if (apps.size() > 0) { // view.getContext().startActivity(intent); // } try { view.getContext().startActivity(intent); } catch (ActivityNotFoundException ex) { } return true; }

It looks like it returns true. Where I was expecting that Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); will be called for deeplink calls.

KojiNakamaru commented 2 weeks ago

The deny pattern simply denies a matched request. I guess you can utilize the hooked pattern instead. When a url is hooked, you can receive it with the hooked callback and open it by Application.OpenURL().

b-phygtl commented 2 weeks ago

I see ! The webview gives me a callback on when an Url is hooked. Let me try that.

Appreciate the help.

b-phygtl commented 1 week ago

Hello again, as a followup on my previous question : Calling Application.OpenURL(url) in the callback of OnHooked on Android platform calls the deeplinks by default. However on iOS it doesnt take the same deeplink flow, rather it opens up a web browser unfortunately.

KojiNakamaru commented 1 week ago

For iOS, how does it work if not calling SetURLPattern()? I guess WKWebView handles a universal link adequately. You can then use #if UNITY_ANDROID to call SetURLPattern() only for Android.

If a universal link targets your app itself, you can utilize SetURLPattern() to hook the link and process it adequately in the hooked callback, without calling Application.OpenURL().

b-phygtl commented 1 week ago

So from the Apple iOS documentation, it looks like if the WkWebview is opening a different scheme type then it supposedly opens the link as universal link. For all other requests like https:// redirects, the WkWebview loads itself. You have to create an activity like this on the objective c code to activate universal links on iOS side.

` NSLog(@"trying deeplink here - URL - %s", nsurl.absoluteString);

    NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:NSUserActivityTypeBrowsingWeb];
    userActivity.webpageURL = nsurl;

    [self webView:[UIApplication sharedApplication] continueUserActivity:userActivity restorationHandler:^(NSArray *restorableObjects){
           // Handle any restorable objects if needed
           NSLog(@"Restoration Handler Called");
    }];

    decisionHandler(WKNavigationActionPolicyCancel);
    return;
}`

I'd like to hear your thoughts on supporting this on Gree. Do you think there is a benefit for adding this feature in Gree plugin ?

KojiNakamaru commented 1 week ago

Your code seems to have some errors, but I hope I could understand it correctly... If we try to treat every https link as a universal link, it should have large overheads. It is better to utilize SetURLPattern() to hook universal links and invoke a separate method that performs your code.

I pushed modified code/binaries to https://github.com/gree/unity-webview/commits/experimental/openuniversallink/ . Though I haven't tested it, it should be utilized as a replacement for Application.OpenURL().

b-phygtl commented 1 week ago

Hi , the code snippets meant to give an example for how we should activate universal link using user activity. It is not meant to assume all links or https as universal links.

Thanks for updating the binaries, I’ll definitely take a look at and it and try out.

KojiNakamaru commented 1 week ago

I've further updated the branch so could you please pull its latest.