How to Open an External Link in Safari Not the App's Uiwebview

How can I open an external link in Safari not the app's UIWebView?

If the links you want to open in safari all contain a common string, you can use the next piece of code.

- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSURL *url = [request URL];

// Intercept the external http requests and forward to Safari.app
// Otherwise forward to the PhoneGap WebView
if ([[url scheme] isEqualToString:@"SCHEME"]) {
[[UIApplication sharedApplication] openURL:url];
return NO;
}
else {
return [ super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType ];
}
}

This code placed in the AppDelegate.m will open all URL that use the specified SCHEME in Safari.

I'm afraid that is all I could come up with.

Hope this helps

UPDATE :

The code should be placed in the MainViewControler, at least for cordova 2.2.0.

The method is initially commented. I had to use it to redirect Google maps links :

NSRange isGoogleMaps = [[url absoluteString] rangeOfString:@"maps.google.com" options:NSCaseInsensitiveSearch];
NSRange isGoogleTerms = [[url absoluteString] rangeOfString:@"terms_maps.html" options:NSCaseInsensitiveSearch];

if(isGoogleMaps.location != NSNotFound || isGoogleTerms.location != NSNotFound ) {
[[UIApplication sharedApplication] openURL:url];
return NO;
}
else
return [super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType];

How to open external link from UIWebView not in my App, but in Safari? SWIFT

@Leo Dabus thanks a lot for this hint, but I guess I have a better solution:

func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
if navigationType == UIWebViewNavigationType.LinkClicked{
UIApplication.sharedApplication().openURL(request.URL!)
return false
}
return true
}

this one works perfect.

Open external link from UIWebView in Safari

You need to handle this in the UIWebView delegate method and check with the UIWebViewNavigationType.

 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{

if(navigationType == UIWebViewNavigationTypeLinkClicked){

[MAIN_APPLICATION_DELEGATE openURL:request.URL];
}
}

WKWebView open links from certain domain in safari

You can implement WKNavigationDelegate, add the decidePolicyForNavigationAction method and check there the navigationType and requested url. I have used google.com below but you can just change it to your domain:

Xcode 8.3 • Swift 3.1 or later

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate {

let webView = WKWebView()

override func viewDidLoad() {
super.viewDidLoad()

webView.frame = view.bounds
webView.navigationDelegate = self

let url = URL(string: "https://www.google.com")!
let urlRequest = URLRequest(url: url)

webView.load(urlRequest)
webView.autoresizingMask = [.flexibleWidth,.flexibleHeight]
view.addSubview(webView)
}

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if navigationAction.navigationType == .linkActivated {
if let url = navigationAction.request.url,
let host = url.host, !host.hasPrefix("www.google.com"),
UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url)
print(url)
print("Redirected to browser. No need to open it locally")
decisionHandler(.cancel)
return
} else {
print("Open it locally")
decisionHandler(.allow)
return
}
} else {
print("not a user click")
decisionHandler(.allow)
return
}
}
}

Open link in Safari from UIWebView

You will need to either grant permission to that specific domain in your info.plist :

<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>testdomain.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSExceptionRequiresForwardSecrecy</key>
<true/>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
<key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
<false/>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<true/>
<key>NSThirdPartyExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
<key>NSRequiresCertificateTransparency</key>
<false/>
</dict>
</dict>
</dict>

This info in your plist basically sets up an exception in your app. It allows you to access the testdomain.com domain (insert whatever domain you are trying to access). It lets you access all of the subdomains and then sets a minimum TLS version to help ensure the site you are connecting to is the one you want.

Or you you can simply allow access to all http websites, which is not recommended.

<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>

This isn't recommended because it allows your app to access any http:// domain, which can be a security problem because it can make your app vulnerable to man-in-the-middle attacks.

Check out Apple's documentation for more info on this.
https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW33

UIWebView open links in Safari

Add this to the UIWebView delegate:

(edited to check for navigation type. you could also pass through file:// requests which would be relative links)

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked ) {
[[UIApplication sharedApplication] openURL:[request URL]];
return NO;
}

return YES;
}

Swift Version:

func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
if navigationType == UIWebViewNavigationType.LinkClicked {
UIApplication.sharedApplication().openURL(request.URL!)
return false
}
return true
}

Swift 3 version:

func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
if navigationType == UIWebViewNavigationType.linkClicked {
UIApplication.shared.openURL(request.url!)
return false
}
return true
}

Swift 4 version:

func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebView.NavigationType) -> Bool {
guard let url = request.url, navigationType == .linkClicked else { return true }
UIApplication.shared.open(url, options: [:], completionHandler: nil)
return false
}

Update

As openURL has been deprecated in iOS 10:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked ) {
UIApplication *application = [UIApplication sharedApplication];
[application openURL:[request URL] options:@{} completionHandler:nil];
return NO;
}

return YES;
}


Related Topics



Leave a reply



Submit