使用WKWebURLSchemeHandler
iOS11以上,苹果为WKWebView增加了WKURLSchemeHandler协议,可以为自定义的Scheme增加遵循WKURLSchemeHandler协议的处理。其中可以在start和stop的时机增加自己的处理。
遵循协议中的两个方法
func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) { let proxy_server = "YourProxyServer" // proxy server
let proxy_port = 1234 // your port
let hostKey = kCFNetworkProxiesHTTPProxy as String
let portKey = kCFNetworkProxiesHTTPPort as String
let proxyDict:[String:Any] = [kCFNetworkProxiesHTTPEnable as String: true, hostKey:proxy_server, portKey: proxy_port] let config = URLSessionConfiguration.ephemeral
config.connectionProxyDictionary = proxyDict
let defaultSession = URLSession(configuration: config)
dataTask = defaultSession.dataTask(with: urlSchemeTask.request, completionHandler: {[weak urlSchemeTask] (data, response, error) in
/// 回调时urlSchemeTask容易崩溃,可能苹果没有考虑会在handler里做异步操作,这里试了一下weak写法,崩溃不出现了,不确定是否为完全解决方案
guard let urlSchemeTask = urlSchemeTask else { return
}
if let error = error {
urlSchemeTask.didFailWithError(error)
} else { if let response = response {
urlSchemeTask.didReceive(response)
}
if let data = data {
urlSchemeTask.didReceive(data)
}
urlSchemeTask.didFinish()
}
})
dataTask?.resume()
}
当然这里URLSession的处理和URLProtocol一样,可以进行复用处理。
然后生成WKWebviewConfiguration,并使用官方API将handler设置进去。
let config = WKWebViewConfiguration()
config.setURLSchemeHandler(HttpProxyHandler(), forURLScheme: "http")//抛出异常
但因为苹果的setURLSchemeHandler只能对自定义的Scheme进行设置,所以像http和https这种scheme,已经默认处理了,不能调用这个API,需要用KVC取值进行设置。
extension WKWebViewConfiguration{ class func proxyConifg() -> WKWebViewConfiguration{ let config = WKWebViewConfiguration() let handler = HttpProxyHandler() /// 先设置
config.setURLSchemeHandler(handler, forURLScheme: "dummy") let handlers = config.value(forKey: "_urlSchemeHandlers") as! NSMutableDictionary
handlers["http"] = handler
handlers["https"] = handler return config
}
}
然后给WKWebview设置就能使用了。
优点:
-
苹果官方方法
-
无审核风险
缺点:
-
仅支持iOS11以上
-
官方不支持非自定义Scheme,非正规设置方法可能出现其他问题