WKWebView在safari中打开来自某个域的链接

Gre*_*ams 35 safari ios swift wkwebview

寻求我的iOS应用程序的一些帮助.在我的应用程序中,我想在WKWebView中打开我的域内的点击链接(EX:communionchapelefca.org),然后在Safari中打开所有其他域(EX:google.com)的链接.我更喜欢以程序方式执行此操作,因为这是我的代码已经设置的方式.

我在stackoverflow上找到了一些解决方案(这里,这里,这里,这里),但它们似乎都是基于Obj-C的,我正在寻找使用Swift的解决方案.提前致谢.

ViewController.swift:

import UIKit
import WebKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let myWebView:WKWebView = WKWebView(frame: CGRectMake(0, 0,   UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height))

        myWebView.loadRequest(NSURLRequest(URL: NSURL(string: "http://www.communionchapelefca.org/app-home")!))

        self.view.addSubview(myWebView)
Run Code Online (Sandbox Code Playgroud)

Leo*_*bus 88

您可以实现WKNavigationDelegate,添加decidePolicyForNavigationAction方法并检查navigationType和请求的URL.我在下面使用了google.com,但您可以将其更改为您的域名:

Xcode 8.3•Swift 3.1或更高版本

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)
            } else {
                print("Open it locally")
                decisionHandler(.allow)
            }
        } else {
            print("not a user click")
            decisionHandler(.allow)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这对我来说并不完全有用,例如,如果你去https://developer.xamarin.com/visual-studio-mac/使用该链接调用devicePolicyForNavitationAction两次,第一次用.LinkActivated和第二种类型与.Other,所以我最终打开浏览器,但也导航webview. (2认同)

Gia*_*mmo 8

对于Swift 3.0

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate {
    let wv = WKWebView(frame: UIScreen.main.bounds)
    override func viewDidLoad() {
        super.viewDidLoad()
        guard let url =  NSURL(string: "https://www.google.com") else { return }
        wv.navigationDelegate = self
        wv.load(NSURLRequest(url: url as URL) as URLRequest)
        view.addSubview(wv)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

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


小智 6

George Vardikos 的 Swift 4 更新回答:

public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        let url = navigationAction.request.url
        guard url != nil else {
            decisionHandler(.allow)
            return
        }

        if url!.description.lowercased().starts(with: "http://") ||
            url!.description.lowercased().starts(with: "https://")  {
            decisionHandler(.cancel)
            UIApplication.shared.open(url!, options: [:], completionHandler: nil)
        } else {
            decisionHandler(.allow)
        }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

以下是来自obj c中写的swift响应的示例代码.

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(nonnull WKNavigationAction *)navigationAction decisionHandler:(nonnull void (^)(WKNavigationActionPolicy))decisionHandler
{
    if (navigationAction.navigationType == WKNavigationTypeLinkActivated) {
        if (navigationAction.request.URL) {
            NSLog(@"%@", navigationAction.request.URL.host);
            if (![navigationAction.request.URL.resourceSpecifier containsString:@"ex path"]) { 
                if ([[UIApplication sharedApplication] canOpenURL:navigationAction.request.URL]) {
                    [[UIApplication sharedApplication] openURL:navigationAction.request.URL];
                    decisionHandler(WKNavigationActionPolicyCancel);
                }
            } else {
                decisionHandler(WKNavigationActionPolicyAllow);
            }
        }
    } else {
        decisionHandler(WKNavigationActionPolicyAllow);
    }
}
Run Code Online (Sandbox Code Playgroud)