LoginSignup
30
42

More than 3 years have passed since last update.

SwiftUIでWebViewを使う

Posted at

令和元年のご時世でもWebViewでラッピングしたアプリを作りたいという要望は多くSwiftUIでWebViewを使う方法について調べたのでメモ
ソースコードはGithubにも上げてあります

開発環境

  • MacOS: 10.14.6
  • Xcode: 11.1

実装

WKWebViewのセットアップ

WKWebViewがないので、UIViewRepresentableを利用してWKWebViewを表示するViewを用意する

WebView.swift
import SwiftUI
import WebKit

struct WebView: UIViewRepresentable {
    var loadUrl:String

    func makeUIView(context: Context) -> WKWebView {
        return WKWebView()
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {
        uiView.load(URLRequest(url: URL(string: loadUrl)!))
    }
}

このWebViewを使えばWebサイトの表示ができる。

ContentView.swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        WebView(loadUrl: "https://www.apple.com")
    }
}

画面遷移を検知する

単純にさっきのWebViewにDelegate追加してstruct WebView: UIViewRepresentable, WKWebViewDelegateみたいにできればいいけど、Classではなく、structなのでエラーが出てしまいdelegateをそのまま実装できない。

今回はObserverを使ってURLの変化を検知して対応した。さっきのWebViewObservableObjectを追加する感じ。

WebView.swift

class observable: ObservableObject {
    @Published var observation:NSKeyValueObservation?
}

struct WebView: UIViewRepresentable {
    var loadUrl:String
    @ObservedObject var observe = observable()

    func makeUIView(context: Context) -> WKWebView {
        return WKWebView()
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {
        observe.observation = uiView.observe(\WKWebView.url, options: .new) { view, change in
            if let url = uiView.url {
                print("Page loaded: \(url)")
            }
        }
        uiView.load(URLRequest(url: URL(string: loadUrl)!))
    }
}

ここではWKWebViewurlを比べているけど、titleや他のプロパティでも可能なので、ロード中かどうか知りたければisLoadingobserveするようにすれば大丈夫。

30
42
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
42