Dev日記

プログラミング学習のまとめなど

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

    • SafariAdBlock系Extensionと同じ書き方
      • 読み込みのブロック
      • 見えなくする
      • SSLSSLに切り替える
  • 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()
}