はじめに
【SwiftUI】WKWebViewを使えるようにする - Swift・iOSの続きです。今回はWKWebViewで表示しているページのURLとタイトルを取得する方法について記載します。
開発環境
- macOS Big Sur 11.2.3
- Xcode 12.4
- Swift 5.3.2
本題
該当のメソッド
WKNavigationDelegateの"webView(_:didFinish:)"で表示しているページの情報を取得できる。
参考:
https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455629-webview
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { // 表示しているページのURL print(webView.url?.absoluteString ?? "") // 表示しているページのタイトル print(webView.title ?? "") }
SwiftUIでの実装例
※【SwiftUI】WKWebViewを使えるようにする - Swift・iOSに該当のメソッドを追加したコードです。
WebView.swift
import SwiftUI import WebKit struct WebView: UIViewRepresentable { var urlString: String class Coordinator: NSObject, WKUIDelegate, WKNavigationDelegate { var parent: WebView init(_ parent: WebView) { self.parent = parent } // "target="_blank""が設定されたリンクも開けるようにする func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? { if navigationAction.targetFrame == nil { webView.load(navigationAction.request) } return nil } // URLごとに処理を制御する func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) { if let url = navigationAction.request.url?.absoluteString { if (url.hasPrefix("https://apps.apple.com/")) { guard let appStoreLink = URL(string: url) else { return } UIApplication.shared.open(appStoreLink, options: [:], completionHandler: { (succes) in }) decisionHandler(WKNavigationActionPolicy.cancel) } else if (url.hasPrefix("http")) { decisionHandler(WKNavigationActionPolicy.allow) } else { decisionHandler(WKNavigationActionPolicy.cancel) } } } // 表示しているページ情報 func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { // 表示しているページのURL print(webView.url?.absoluteString ?? "") // 表示しているページのタイトル print(webView.title ?? "") } } func makeCoordinator() -> Coordinator { Coordinator(self) } func makeUIView(context: Context) -> WKWebView { let webView = WKWebView() return webView } func updateUIView(_ webView: WKWebView, context: Context) { // makeCoordinatorで生成したCoordinatorクラスのインスタンスを指定 webView.uiDelegate = context.coordinator webView.navigationDelegate = context.coordinator // スワイプで画面遷移できるようにする webView.allowsBackForwardNavigationGestures = true guard let url = URL(string: urlString) else { return } let request = URLRequest(url: url) webView.load(request) } }
おわりに
デリゲートメソッドで取得したページ情報の共有方法ですが、SwiftUIの場合は、@Bindingなどで監視するよりも、NotificationCenterなどの通知を使用した方が呼び出し側の実装がすっきりするような気がしました。