WKWebViewのUserAgentを変更する

## 背景
Web側がスマートフォンからのアクセスで、Safari以外のブラウザの場合にデータのアップロードができない仕様となっていた。
サーバーサイドに対応を依頼するにしても時間がかかることが考えられるので、一旦アプリ側でUserAgentを偽装することに。

## 偽装するUserAgentの確認
PCのchromeで以下にアクセスすると、ユーザーエージェントが確認できる。
→chrome://version/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245300/3ee0b266-8265-b791-15f1-58c7fc388f11.png)

# WKWebViewでUserAgentを設定する
3つくらい方法があるらしいので、用途によって使い分ける感じです

### 1. UserDefaultsのUserAgentを変更する方法
- WebView生成前にUserDefaultsに対して、先程PCで確認したカスタムUserAgentを設定する（WKWebView生成前に設定が必要となる）

```Hoge.swift
UserDefaults.standard.register(defaults: ["UserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"])
```

...Xcode15 x iOS17の組み合わせだと使えないらしい？→[Xcode15でビルドするとUserDefaultsからのUserAgentの変更ができなくなる(iOS17のみ)](https://qiita.com/yanamura/items/8828bb885ddc71f7eabd)

これはUIWebViewみたいですが一応…
[UserAgent cannot be changed from UserDefaults only iOS 17 Device using Xcode 15](https://stackoverflow.com/questions/77305552/useragent-cannot-be-changed-from-userdefaults-only-ios-17-device-using-xcode-15)

### 2. customUserAgentを使う方法
- WebViewの[customUserAgent](https://developer.apple.com/documentation/webkit/wkwebview/1414950-customuseragent)に対してUserAgentを設定する（WKWebView生成後に設定）

```Hoge.swift
webView.customUserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
```

### 3. applicationNameForUserAgentを使う方法（未検証）
- [applicationNameForUserAgent](https://developer.apple.com/documentation/webkit/wkwebviewconfiguration/1395665-applicationnameforuseragent)を使う方法もあるようです


### WebViewに設定されているUserAgentの確認方法

```Hoge.swift
webView.evaluateJavaScript("navigator.userAgent;") { result, error in
    if let error = error {
        print(error)
        return
    }
    print("UserAgent: \(result ?? "nil")")
}
```

# おまけ
## デフォルトのUserAgentの末尾に情報を追加してみる（customUserAgent）
用途："デフォルトのUserAgent" + "バンドルID" + "アプリバージョン"としたい場合など

### デフォルトUserAgentの取得

```Hoge.swift
webView.evaluateJavaScript("navigator.userAgent;") { [weak self] result, error in
    guard let self = self else { return }
    if let defaultUserAgent = result as? String {
    }
}
```

### バンドルIDの取得

```Hoge.swift
let appBundleId = Bundle.main.bundleIdentifier ?? ""
```

### アプリバージョンの取得

```Hoge.swift
let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? ""
```


### "デフォルトのUserAgent" + "バンドルID" + "アプリバージョン"

```Hoge.swift
webView.evaluateJavaScript("navigator.userAgent;") { [weak self] result, error in
    guard let self = self else { return }
    if let defaultUserAgent = result as? String {
        let appBundleId = Bundle.main.bundleIdentifier ?? ""
        let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? ""
        let userAgent = "\(defaultUserAgent) \(appVersion)"
        self.webView.customUserAgent = userAgent
    }
}
```

## 参考
- [customUserAgent](https://developer.apple.com/documentation/webkit/wkwebview/1414950-customuseragent)
- [applicationNameForUserAgent](https://developer.apple.com/documentation/webkit/wkwebviewconfiguration/1395665-applicationnameforuseragent)
- [applicationNameForUserAgent](https://developer.apple.com/documentation/webkit/wkwebviewconfiguration/1395665-applicationnameforuseragent)
- [Xcode15でビルドするとUserDefaultsからのUserAgentの変更ができなくなる(iOS17のみ)](https://qiita.com/yanamura/items/8828bb885ddc71f7eabd)
- [UserAgent cannot be changed from UserDefaults only iOS 17 Device using Xcode 15](https://stackoverflow.com/questions/77305552/useragent-cannot-be-changed-from-userdefaults-only-ios-17-device-using-xcode-15)