xyk blog

最近は iOS 開発の記事が多めです。

UIWebViewのリクエストにUserAgentを設定する

環境: Swift3

UIWebViewのリクエストにUserAgentを設定するには、リクエスト前にUserDefaultsのregisterメソッドでキー名UserAgentで値をセットする必要がある。

UserDefaults.standard.register(defaults: ["UserAgent" : "hoge"])

この時、

// これだと設定されない
UserDefaults.standard.set("hoge", forKey: "UserAgent")

のようにUserDefaultsに普通に保存してもダメでregisterメソッドでデフォルト値として設定すること。

// これを使う
open func register(defaults registrationDictionary: [String : Any])

setメソッドとregisterメソッドの違いは以下参照。
xyk.hatenablog.com


追記

ハマリポイントがあったのでメモ。

UIWebViewで使われるUserAgentを取得する方法は以下。

let ua: String? = webView.stringByEvaluatingJavaScript(from: "navigator.userAgent")

取得結果は

Mozilla/5.0 (iPhone; CPU iPhone OS 10_2 like Mac OS X) AppleWebKit/602.3.12 (KHTML, like Gecko) Version/10.0 Mobile/14C92 Safari/602.1

となった。
この結果の末尾に独自の文字列(ここでは例としてhoge)を追加して

Mozilla/5.0 (iPhone; CPU iPhone OS 10_2 like Mac OS X) AppleWebKit/602.3.12 (KHTML, like Gecko) Version/10.0 Mobile/14C92 Safari/602.1 hoge

これを新たなUserAgentとして更新しようとしたがなぜか更新できなかった。
どうやら使用するUIWebViewのインスタンスに対してwebView.stringByEvaluatingJavaScript(from: "navigator.userAgent")を呼び出すとそれ以降、UserAgentを設定しても更新できないようだ。

なので、以下のようにした。

class WebViewController: UIViewController {

   @IBOutlet weak var webView: UIWebView?

    override func loadView() {
        
        self.updateUserAgent()
        super.loadView()
    }

    func updateUserAgent() {
        guard
            let currentUserAgent = UIWebView().stringByEvaluatingJavaScript(from: "navigator.userAgent"),
            !currentUserAgent.contains("hoge")
        else {
            return
        }
        
        let newUserAgent = "\(currentUserAgent) hoge"
        let dic = ["UserAgent" : newUserAgent]
        UserDefaults.standard.register(defaults: dic)
    }

}

実際に使用するself.webViewには触れず、またself.webViewを使用する前に、新たなUIWebViewインスタンスを作って、そこから元のUserAgentを取り出して更新するようにした。

一度更新すればアプリ内では引き継がれるのでapplication:didFinishLaunchingWithOptionsでやってしまっても良いと思う。