WWDC 2017 Customized Loading in WKWebView まとめ
WKWebViewの新機能に関する話
動画はこちら
Customized Loading in WKWebView
WebContentsを表示するにはいくつかの方法がある
- WKWebView
- SFSafariController
SFSafariControllerを使えばボタン等をOS側で処理してくれて楽
- ただし画面の一部に組み込みたいときには使えない
- その場合は
WKWebView
WKWebViewのプロセスはAppと分離される
- セキュリティ上の理由など
- それによる制約も強かった
今回は開発者から要望の多かった機能を3つ実装した
- Manage Cookies
- Filter unwatned content
- Provide custom resources
Manage Cookies
- WKHttpCookieStore
- クッキーを個別に追加/削除できる
- すべてのクッキーにアクセス可能
- クッキーの変更を監視可能
//GET let cookieStore = webView.configuration.websiteDataStore.httpCookieStore; cookieStore.getAllCookies() {(cookies) in } //ADD let cookie = HTTPCookie(properties: [ HTTPCookiePropertyKey.domain: "canineschool.org", HTTPCookiePropertyKey.path: "/", HTTPCookiePropertyKey.secure: true, HTTPCookiePropertyKey.name: "LoginSessionID", HTTPCookiePropertyKey.value: "5bd9d8cabc46041579a311230539b8d1"]) cookieStore.setCookie(cookie!) { webView.load(loggedInURLRequest) } //remove cookieStore.delete(cookie!) { webView.load(loggedOutURLRequest) }
Filtering unwanted content
見せたくないコンテンツをブロックできる
WKContentRuleList
JSONで記述、コード中でロードしWebViewに適用させる
//json-file in Bundle [{ "trigger": { "url-filter": ".*" }, "action": { "type": "make-https" } }] //swift-code //compile let jsonString = loadJSONFromBundle() WKContentRuleListStore.default().compileContentRuleList( forIdentifier: "ContentBlockingRules", encodedContentRuleList: jsonString ) { (contentRuleList, error) in if let error = error { return } createWebViewWithContentRuleList(ruleList!) } //access rules WKContentRuleListStore.default() .lookUpContentRuleList( forIdentifier: "ContentBlockingRules") { (contentRuleList, error) in //取得した情報を使う部分 } //apply let configuration = WKWebViewConfiguration() configuration.userContentController.add(contentRuleList)
Provide custom resources
- リソース読み込みをアプリで処理できるようになる
- ただしカスタムURLスキームに限る?)
将来的にも問題ないようにカスタムスキームを設定するように
- Bad : local
- Good : [AppName]-local
WKURLSchemeHandler を使う
class MyCustomSchemeHandler : NSObject, WKURLSchemeHandler { func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {} func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {} } let configuration = WKWebViewConfiguration() configuration.setURLSchemeHandler(MyCustomSchemeHandler(), forURLScheme: “custom-scheme")
WKURLSchemeTask
に結果を渡す
func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) { //Bundleからデータを読み込み、対応するResponseクラスを作成し渡す let resourceData : Data = loadDataFromBundle() let response = URLResponse( url: urlSchemeTask.request.url, mimeType: "text/html", //mimeType必須 expectedContentLength : resourceData.count, textEncodingName : nil ) urlSchemeTask.didReceive(response) urlSchemeTask.didReceive(resourceData) urlSchemeTask.didFinish() }