webviewでのデータのやり取りの検証を、swiftuiで行ってみました。
デジタルマーケティングなどで、アプリの行動を見るときに、
ネイティブ要素とwebview要素が混在しているとき、ユーザーの動きをどのようにして把握できるのかをふと思い、ちょっと検証してみます!
import SwiftUI @main struct TestWebViewApp: App { var body: some Scene { WindowGroup { ContentView() } } }
import SwiftUI struct ContentView: View { @State var web_flg:Bool = true var body: some View { VStack { if(web_flg){ Text("Hello, world!") Button(action: { self.web_flg = false; }, label: { Text("WebView Open") }) } else { WebView() } } .padding() } }
swiftuiでは現時点ではwebviewサポートしていないので、swiftでwebviewを作成しつつ、それをswiftuiで表示するような変換を施します。
import UIKit import SwiftUI import WebKit /** ViewControllerからViewへ変換 */ struct WebView : UIViewControllerRepresentable { func makeUIViewController(context: Context) -> ViewController1 { return ViewController1() } func updateUIViewController(_ uiViewController: ViewController1, context: Context) { } } class ViewController1: UIViewController { var webView: WKWebView! override func viewDidLoad() { super.viewDidLoad() webView = WKWebView(frame: view.frame) view.addSubview(webView) let request = URLRequest(url: URL(string: "https://yosshiblog.jp/?test=1")!) webView.load(request) // webviewのcookieの一覧を取得 webView.configuration.websiteDataStore.httpCookieStore.getAllCookies { for cookie in $0 { print(cookie.name) } } } } extension ViewController1: WKNavigationDelegate { // ページの読み込み開始時に呼ばれる func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { print("----------------------------") print("Start Provisional Navigation") print("----------------------------") } // ページの内容受信開始時に呼ばれる func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) { print("Did Commit") } // ページの読み込み完了時に呼ばれる func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { print("Did Finish") } // ページの読み込みエラー発生時に呼ばれる func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) { print("Did Fail Provisional Navigation") } }
検証パターン
検証としては①ネイティブからwebviewへのデータ受け渡し、そして②webviewでのデータをネイティブへ受け渡しの2パターンになります。
パターン①
これについては上のコードを見てもらうとわかる通り、
webviewを表示するには、引数に表示したいURLを記載する必要があります。
なのでwebサーバにリクエストして表示させるわけですが、リクエストするのでもちろんwebの仕組みと同様にクエリパラメータなどをURLに付与してwebviewに送ることができるということになります。
これはシンプルで当たり前に思いますね!
クエリパラメータを付与するということはGET通信によるリクエスト方法ですが、実際にjson形式にしてペイロードで送るPOST通信をすることも可能です。
なので、ネイティブ内にてユーザーのログインIDであったりセッション情報や、IDFAなどのデバイスID等も取得して、webviewに送ることは可能ということになります。
パターン②
これについては、どのようにすればwebviewからネイティブに値を受け渡すことができるのでしょうか。
webviewからネイティブに渡すので、webviewを起点としてネイティブ方向に渡す処理を書く必要があるのかというとそういうものではありません。
結論を言うと、ネイティブアプリから能動的にwebviewのデータを取りにいくということになります。
では、どのように取りにいくのか。
それは、「webviewを閉じたとき」というトリガーを用いることで、取得することが可能です。
webviewが閉じた時に呼ばれる関数として、didFinishという関数があります。
この中にて、webviewにあるデータをjavascriptを用いてとってくることが可能です。javascrip内に欲しいデータを吐き出してしまえば、どんなデータもwebviewからネイティブに渡すことができるということになります。