概要
アプリを作っているとネイティブとWebViewが混在して実装することが多いと思います。
特に、Web版からアプリを作りたいという時に多いです。
今回は、WebViewのイベントをフックして、ネイティブで処理する際のメモを共有します。
やるべきこと
- WebViewにネイティブへリダイレクトする処理を追加する。
- ネイティブにWebViewからのリダイレクトされたときの受け口を追加する。
今回例示するシーン
ログイン後にWebからトークンIDを取得する。
今回は、WebViewの説明は割愛します。
1. WebViewにネイティブへリダイレクトする処理を追加する。
WebViewでログインボタンを押下した際に、
ネイティブにリダイレクトする処理を追加する必要があります。
例)
header("Location: sdt://login?tokenID=1234567890")
WebViewからネイティブへフックするときのインタフェースについて
sdt://login?tokenID=1234567890
キー | 説明 |
---|---|
sdt:// | URLスキーム |
login | アクション名 |
tokenID | トークンID(パラメタ) |
2. ネイティブにWebViewからのリダイレクトされたときの受け口を追加する。
実装のポイント
WebViewのshouldStartLoadWithRequestの戻り値に下記の値を返す
①URLスキームが「http」 or 「https」の場合は、「true」を返す
②URLスキームが「sdt」の場合は、「false」を返す
falseを返すと、処理を中断するため、
このタイミングでWebViewからネイティブへフックされる。
参考ソースコード
//MARK: - UIWebViewDelegate
extension ViewController: UIWebViewDelegate {
func webView(webView: UIWebView, shouldStartLoadWithRequest
request: NSURLRequest,
navigationType: UIWebViewNavigationType) -> Bool {
if let scheme = request.URL?.scheme where scheme.hasPrefix("http") {
return true
}
if let action = request.URL?.description, let query = request.URL?.query {
let queryDic = QueryParser.queryDictionary(query)
//ログインボタンが押下された時の処理を行う
if action.hasPrefix("sdt://login") {
print(queryDic["tokenID"])
}
}
return false
}
}
パラメタの受け取り
今回パラメタの受け取りは、下記のようなクラスを作成しました。
import Foundation
class QueryParser {
class func queryDictionary(query: String) -> [String:String]{
var querys = [String: String]()
let pairs = query.componentsSeparatedByString("&");
for pair in pairs {
let elements = pair.componentsSeparatedByString("=")
let key = elements[0].stringByRemovingPercentEncoding
let value = elements[1].stringByRemovingPercentEncoding
if let key = key, value = value {
querys[key] = value
}
}
return querys
}
}
パラメタが複数ある場合も確認しておきます。
import XCTest
@testable import WebViewBridge
class QueryParserTests: XCTestCase {
override func setUp() {
super.setUp()
}
override func tearDown() {
super.tearDown()
}
func testQuery() {
let query = QueryParser.queryDictionary("tokenID=12345678&name=sdt&age=6&numbers=40")
XCTAssertEqual(query["tokenID"], "12345678")
XCTAssertEqual(query["name"], "sdt")
XCTAssertEqual(query["age"], "6")
XCTAssertEqual(query["numbers"], "40")
}
}
まとめ
- WebViewにネイティブへリダイレクトする処理を追加する。
- ネイティブにWebViewからのリダイレクトされたときの受け口を追加する。
こちらも合わせて読んでください♥
[WebViewシリーズ①] WebViewのイベントをフックする
[WebViewシリーズ②] WebView内でJavaScriptのメソッドを操作する
[WebViewシリーズ③] WebViewは、ページ内のアンカーへリンクできない??
[WebViewシリーズ④] WebView(アプリ内)のリンクからiTunesが表示できない
ゆるふわにUIWebViewでJavaScriptイベントをひろってみる
誤り等ございましたら、ご指摘頂ければ幸いです。