WKWebView设置UserAgent踩坑
通过下面的方法给wkwebview设置自定义useragent,解决了常见的问题,如第一次设置不生效,第一次获取不到原来的useragent等问题
思路如下
单个webview设置:iOS9.0以后,可以设置customUserAgent
来单个设置webview的自定义useragent
全局设置:先通过evaluateJavaScript("navigator.userAgent")
获取原来的useragent,然后追加自定义useragent,通过UserDefaults.standard.register(defaults: ["UserAgent": newAgent])
全局设置
代码如下
import UIKit
import WebKit
class WebViewManager: NSObject {
static let shared = WebViewManager()
var webView: WKWebView?
private var isAddCustomUserAgent: Bool = false
func loadHtmlString(_ htmlString: String) {
// 单个设置webview的userAgent
// addCustomUserAgent()
// webView?.loadHTMLString(htmlString)
// webView?.evaluateJavaScript("navigator.userAgent") { (oldAgent, error) in
// guard let oldAgent = oldAgent as? String else {
// print("没取到oldAgent")
// return
// }
// print("设置后的新的user agent:\(oldAgent)")
// }
// 全局设置userAgent
addCustomUserAgent { [weak self] in
// 一定要在useragent设置完成后在加载html页面
self?.webView?.loadHTMLString(htmlString)
self?.webView?.evaluateJavaScript("navigator.userAgent") { (oldAgent, error) in
guard let oldAgent = oldAgent as? String else {
print("没取到oldAgent")
return
}
print("设置后的新的user agent:\(oldAgent)")
}
}
}
}
extension WebViewManager {
// 单个webview设置useragent
private func addCustomUserAgent() {
let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? ""
let token = Authentication.shared.user?.accessToken ?? ""
let refreshToken = Authentication.shared.user?.refreshToken ?? ""
let customUserAgent = ";POSApp;platform=iOS;version=\(version);token=\(token);refreshToken=\(refreshToken)"
webView?.customUserAgent = customUserAgent
}
// 全局设置useragent
private func addCustomUserAgent(completed: @escaping ()->()) {
guard !isAddCustomUserAgent else {
print("不再重新设置agent")
completed()
return
}
// 这个地方使用evaluateJavaScript的webview一定要添加到界面的,不然取不到oldAgent
webView?.evaluateJavaScript("navigator.userAgent") { [weak self] (oldAgent, error) in
let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? ""
let token = Authentication.shared.user?.accessToken ?? ""
let refreshToken = Authentication.shared.user?.refreshToken ?? ""
let customUserAgent = ";POSApp;platform=iOS;version=\(version);token=\(token);refreshToken=\(refreshToken)"
guard let oldAgent = oldAgent as? String else {
print("evaluateJavaScript取不到旧的agent")
let oldAgent = "Mozilla/5.0 (\(UIDevice.current.model); CPU iPhone OS \(UIDevice.current.systemVersion.replacingOccurrences(of: ".", with: "_")) like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148"
let newAgent = "\(oldAgent)\(customUserAgent)"
// 设置global User-Agent
UserDefaults.standard.register(defaults: ["UserAgent": newAgent])
// 一定要设置customUserAgent,因为全局useragent只会在设置后添加的webview生效
self?.webView?.customUserAgent = newAgent
self?.isAddCustomUserAgent = true
print("evaluateJavaScript设置新的agent:\(newAgent)")
completed()
return
}
guard !oldAgent.hasSuffix(customUserAgent) else {
print("evaluateJavaScript已经设置新的agent")
completed()
return
}
let newAgent = "\(oldAgent)\(customUserAgent)"
UserDefaults.standard.register(defaults: ["UserAgent": newAgent])
// 一定要设置customUserAgent,因为全局useragent只会在设置后添加的webview生效
self?.webView?.customUserAgent = newAgent
self?.isAddCustomUserAgent = true
print("evaluateJavaScript设置新的agent:\(newAgent)")
completed()
}
}
}
补充
真是too long too simple (_)v
这样设置有两个个坑
1、切换useragent某些场景下也会失效。
2、第一次安装app,进入webview,设置useragent会失效;
没搞清楚具体原因是什么,但是找到了解决办法:
1、加载时强制不适用任何缓存
let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData)
webView?.load(request)
webView?.reloadFromOrigin()
2、调用load后再设置一次customUserAgent
webView?.customUserAgent = customUserAgent
loadHTMLString(("\(self.webHostUrlString)\(self.htmlPath ?? "")"))
webView?.customUserAgent = customUserAgent
后来发现完全是多此一举了,其实是web端的bug
3、先获取原来的,再追加
private func addCustomUserAgent(completed: @escaping ()->()) {
self.fakeWebView = WKWebView()
self.fakeWebView?.evaluateJavaScript("navigator.userAgent") { [weak self] (oldAgent, error) in
self?.fakeWebView = nil
guard let oldAgent = oldAgent as? String else {
let oldAgent = "Mozilla/5.0 (\(UIDevice.current.model); CPU iPhone OS \(UIDevice.current.systemVersion.replacingOccurrences(of: ".", with: "_")) like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148"
let newAgent = "\(oldAgent)\(self?.customUserAgent ?? "")"
self?.webView?.customUserAgent = newAgent
completed()
return
}
let newAgent = "\(oldAgent)\(self?.customUserAgent ?? "")"
self?.webView?.customUserAgent = newAgent
completed()
}
}
好了,问题总算比较完美的解决了^ - ^