10
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SwiftからJavascript(Ajax)で利用する認証情報を設定する

Last updated at Posted at 2016-11-07

iOSのアプリ開発において、一部の機能についてはWebviewを利用してHTMLをする画面を作る際、単純なHTMLの表示だけではなくJavascriptで非同期にデータを取得して、HTMLをレンダリングすることもあります。
もし、アプリ-サーバ間でユーザ認証を行っている場合、次のタイミングでサーバ側に認証情報を送る必要があります。

  1. HTML取得時(HTTPリクエストによる同期通信)
  2. Javascriptコード内での非同期通信

今回、iOSネイティブ側からWebviewのJavascriptへ認証情報を渡す方法をまとめます。
前提として

  • iOSネイティブ側で認証情報を既に保持している
  • WebviewはWKWebViewを使用する
  • 認証情報はヘッダー情報にtokenとして設定する

動作環境

  • Xcode 8.1
  • Swift 3.0.1

HTML取得時に認証情報を設定する

WKWebViewのloadで送信するURLRequestのヘッダー情報にtoken情報を設定するだけです。

let token = `token情報`
guard let url = URL(string: `エントリポイントのURL`) else { return }
let request = URLRequest(url: url)
request.addValue(token, forHTTPHeaderField: "Auth-Token")

webView.load(request)

SwiftからWkWebViewのJavascriptに認証情報を渡す

HTMLの読込後に実行されるJavascript内で非同期でデータ取得を行う場合は、実行前に認証情報を設定しておく必要があります。

①DOM構築 -> ②アプリケーションスクリプト実行

②より前のタイミングでSwiftからJavascriptへ認証情報を渡す必要がある

iOS側のコードは次のようになります。

let token = `token情報`
let jsSrc = "AppConfig = {}; AppConfig.authToken = '\(token)';"
let script = WKUserScript(source: jsSrc, injectionTime: .atDocumentStart, forMainFrameOnly: true)
webView.configuration.userContentController.addUserScript(script)

ポイントはWKUserScriptで指定するinjectionTimeにWKUserScriptInjectionTime.atDocumentStartを設定すること。
この設定によりWKWebViewがDOMを生成した直後に、指定したスクリプトを実行してくれます(他のコンテンツをロードする前に実行されます)
injectionTimeにWKUserScriptInjectionTime.atDocumentEndを指定した場合、スクリプトの実行や、他のコンテンツの読込が終わった後にWKUserScriptで定義したjavasriptが実行されるため、認証情報がないまま非同期通信を行うことになります。最後にHTMLを更新する場合などに適しています。

javascript側の利用例

ネイティブ側から渡された認証情報をJavascript側から利用する例です。

jQuery Ajaxで利用する場合

jQuery
$.ajax({
  url: `APIのエンドポイント`,
  type: 'GET',
  dataType: 'json',
  headers: {
    'Auth-Token': AppConfig.authToken
  }
  success: function(res, status, xhr) {
    // do something
  }
  error: (xhr, status, error) {
    // do something
  }
})

fetch APIを利用する場合(ES6などを利用している場合は、こちらを利用するケースが多いでしょうか)

whatwg-fetch

fetch(`APIのエンドポイント`, {
  headers: {
    'Auth-Token': AppConfig.authToken
  }
})
.then(response =>
	// do something
)

iOS側のコード最終形

import WebKit

class WebViewController: UIViewController {

    @IBOutlet weak var webview: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Javascript内のAjaxで利用するための設定
        let token = `token情報`
        let jsSrc = "AppConfig = {}; AppConfig.authToken = '\(token)';"
        let script = WKUserScript(source: jsSrc, injectionTime: .AtDocumentStart, forMainFrameOnly: true)
        webView.configuration.userContentController.addUserScript(script)

        // HTML取得時の認証情報設定
        guard let url = URL(string: `エントリポイントのURL`) else { return }
        let request = URLRequest(url: url)
        request.addValue(token, forHTTPHeaderField: "Auth-Token")

        webView.load(request)
    }
}
10
11
0

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
10
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?