一旦已经在 WebView 中,如何使用 WKWebView 打开外部 link?
How to open external link with WKWebView once already inside WebView?
我一直在 YouTube 上,所以,google 过去 3 小时,我找不到答案。
我可以通过 webView 打开初始 link 到 instagram,一旦我进入 webView 并转到某人的简历并按任何 link 他们没有任何反应。
我去了 .plist
并启用了 App Transport Security > Arbitrary Loads > YES
我尝试了 decidePolicyFor navigationAction: WKNavigationAction
但没有任何反应:
class ViewController: WKNavigationDelegate {
var webView: WKWebView!
override func loadView() {
webView = WKWebView()
webView.navigationDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
guard let url = URL(string: "https://www.instagram.com/apple") else { return }
let request = URLRequest(url: url)
webView.load(request)
webView.allowsBackForwardNavigationGestures = true
webView.addObserver(self, forKeyPath: #keyPath(WKWebView.isLoading), options: [.new], context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "loading" {
if webView.isLoading {
view.addSubview(spinner)
} else {
spinner.removeFromSuperview()
}
}
}
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
if navigationAction.targetFrame == nil {
webView.load(navigationAction.request)
}
return nil
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
switch navigationAction.navigationType {
case .linkActivated:
if navigationAction.targetFrame == nil {
self.webView?.load(navigationAction.request)
}
if let url = navigationAction.request.url, !url.absoluteString.hasPrefix("http://www.myWebSite.com/example") {
DispatchQueue.main.async {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
print(url.absoluteString)
decisionHandler(.cancel)
return
}
default:
break
}
if let url = navigationAction.request.url {
print(url.absoluteString)
}
decisionHandler(.allow)
}
// tried this too
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
var action: WKNavigationActionPolicy?
defer {
decisionHandler(action ?? .allow)
}
guard let url = navigationAction.request.url else { return }
print(url)
if navigationAction.navigationType == .linkActivated, url.absoluteString.hasPrefix("http://www.example.com/open-in-safari") {
action = .cancel
DispatchQueue.main.async {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}
}
}
您还需要遵守 WKUIDelegate
。
webView.uiDelegate = self
因为你没有,所以这个委托方法没有触发。
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView?
我一直在 YouTube 上,所以,google 过去 3 小时,我找不到答案。
我可以通过 webView 打开初始 link 到 instagram,一旦我进入 webView 并转到某人的简历并按任何 link 他们没有任何反应。
我去了 .plist
并启用了 App Transport Security > Arbitrary Loads > YES
我尝试了 decidePolicyFor navigationAction: WKNavigationAction
但没有任何反应:
class ViewController: WKNavigationDelegate {
var webView: WKWebView!
override func loadView() {
webView = WKWebView()
webView.navigationDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
guard let url = URL(string: "https://www.instagram.com/apple") else { return }
let request = URLRequest(url: url)
webView.load(request)
webView.allowsBackForwardNavigationGestures = true
webView.addObserver(self, forKeyPath: #keyPath(WKWebView.isLoading), options: [.new], context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "loading" {
if webView.isLoading {
view.addSubview(spinner)
} else {
spinner.removeFromSuperview()
}
}
}
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
if navigationAction.targetFrame == nil {
webView.load(navigationAction.request)
}
return nil
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
switch navigationAction.navigationType {
case .linkActivated:
if navigationAction.targetFrame == nil {
self.webView?.load(navigationAction.request)
}
if let url = navigationAction.request.url, !url.absoluteString.hasPrefix("http://www.myWebSite.com/example") {
DispatchQueue.main.async {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
print(url.absoluteString)
decisionHandler(.cancel)
return
}
default:
break
}
if let url = navigationAction.request.url {
print(url.absoluteString)
}
decisionHandler(.allow)
}
// tried this too
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
var action: WKNavigationActionPolicy?
defer {
decisionHandler(action ?? .allow)
}
guard let url = navigationAction.request.url else { return }
print(url)
if navigationAction.navigationType == .linkActivated, url.absoluteString.hasPrefix("http://www.example.com/open-in-safari") {
action = .cancel
DispatchQueue.main.async {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}
}
}
您还需要遵守 WKUIDelegate
。
webView.uiDelegate = self
因为你没有,所以这个委托方法没有触发。
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView?