Ios WKWebView:在多个视图控制器中使用相同的代理代码(WKNavigationDelegate)

Ios WKWebView:在多个视图控制器中使用相同的代理代码(WKNavigationDelegate),ios,swift,xcode,Ios,Swift,Xcode,我有一个带有5个导航选项卡的应用程序,每个选项卡都有一个不同的视图控制器,其中包含一个WKWebView。我希望以某种方式使用相同的委托代码来防止在每个委托代码中复制和粘贴 如何在不同的视图控制器中重用“decidePolicyFor”代码? class DashboardViewController: UIViewController, WKUIDelegate, WKNavigationDelegate { var webView: WKWebView! override

我有一个带有5个导航选项卡的应用程序,每个选项卡都有一个不同的视图控制器,其中包含一个WKWebView。我希望以某种方式使用相同的委托代码来防止在每个委托代码中复制和粘贴

如何在不同的视图控制器中重用“decidePolicyFor”代码?

class DashboardViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {

    var webView: WKWebView!

    override func loadView() {
        let webConfiguration = WebViewUtils.getWKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.uiDelegate = self
        webView.navigationDelegate = self
        view = webView
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        webView.load(Constants.DASHBOARD)
    }

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

        if navigationAction.request.url?.scheme == "tel" {
            UIApplication.shared.open(navigationAction.request.url!, options: convertToUIApplicationOpenExternalURLOptionsKeyDictionary([:]), completionHandler: nil)
            decisionHandler(.cancel)
        }
        else {
            decisionHandler(.allow)
        }
    }
}

您可以通过
依赖项注入来实现这一点,如下所示:

class NavigationBehavior: NSObject, WKNavigationDelegate {
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        if let url = navigationAction.request.url, url.scheme == "tel" {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
            decisionHandler(.cancel)
        } else {
            decisionHandler(.allow)
        }
    }
}

class DashboardViewController: UIViewController, WKUIDelegate {

    lazy var webView: WKWebView = {
        let webConfiguration = WKWebViewConfiguration()
        return WKWebView(frame: .zero, configuration: webConfiguration)
    }()

    let navigationDelegate: WKNavigationDelegate
    init(navigationDelegate: WKNavigationDelegate) {
        self.navigationDelegate = navigationDelegate
        super.init(nibName: nil, bundle: nil)
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func loadView() {
        webView.uiDelegate = self
        webView.navigationDelegate = navigationDelegate
        view = webView
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        webView.load(Constants.DASHBOARD)
    }

}

let delegate = NavigationBehavior()
let vc1 = DashboardViewController(navigationDelegate: delegate)
let vc2 = ProfileViewController(navigationDelegate: delegate)

您可以通过
依赖项注入来实现这一点,如下所示:

class NavigationBehavior: NSObject, WKNavigationDelegate {
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        if let url = navigationAction.request.url, url.scheme == "tel" {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
            decisionHandler(.cancel)
        } else {
            decisionHandler(.allow)
        }
    }
}

class DashboardViewController: UIViewController, WKUIDelegate {

    lazy var webView: WKWebView = {
        let webConfiguration = WKWebViewConfiguration()
        return WKWebView(frame: .zero, configuration: webConfiguration)
    }()

    let navigationDelegate: WKNavigationDelegate
    init(navigationDelegate: WKNavigationDelegate) {
        self.navigationDelegate = navigationDelegate
        super.init(nibName: nil, bundle: nil)
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func loadView() {
        webView.uiDelegate = self
        webView.navigationDelegate = navigationDelegate
        view = webView
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        webView.load(Constants.DASHBOARD)
    }

}

let delegate = NavigationBehavior()
let vc1 = DashboardViewController(navigationDelegate: delegate)
let vc2 = ProfileViewController(navigationDelegate: delegate)

您可以在如下对象中提取导航代理代码:

class MyWebViewNavigationDelegate: NSObject, WKNavigationDelegate {
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        if navigationAction.request.url?.scheme == "tel" {
            UIApplication.shared.open(navigationAction.request.url!, options: [:], completionHandler: nil)
            decisionHandler(.cancel)
        } else {
            decisionHandler(.allow)
        }
    }
}
然后在整个应用程序中使用此对象的实例:

class DashboardViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {

    var webView: WKWebView!
    let webViewNavigationDelegate = MyWebViewNavigationDelegate()

    override func loadView() {
        let webConfiguration = WebViewUtils.getWKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.uiDelegate = self
        webView.navigationDelegate = webViewNavigationDelegate
        view = webView
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        webView.load(Constants.DASHBOARD)
    }
}

您可以在如下对象中提取导航代理代码:

class MyWebViewNavigationDelegate: NSObject, WKNavigationDelegate {
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        if navigationAction.request.url?.scheme == "tel" {
            UIApplication.shared.open(navigationAction.request.url!, options: [:], completionHandler: nil)
            decisionHandler(.cancel)
        } else {
            decisionHandler(.allow)
        }
    }
}
然后在整个应用程序中使用此对象的实例:

class DashboardViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {

    var webView: WKWebView!
    let webViewNavigationDelegate = MyWebViewNavigationDelegate()

    override func loadView() {
        let webConfiguration = WebViewUtils.getWKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.uiDelegate = self
        webView.navigationDelegate = webViewNavigationDelegate
        view = webView
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        webView.load(Constants.DASHBOARD)
    }
}