Last active
January 30, 2018 13:13
-
-
Save acalism/b5e3155719d778ca2d229932dbccd96b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension WKWebView { | |
/// sync version | |
/// | |
/// - Parameters: | |
/// - js: 要执行的javascript代码 | |
/// - timeout: 限时返回(单位秒),0表示不限时 | |
/// - Returns: 执行结果 | |
func evaluatingJavaScript(_ js: String, timeout: TimeInterval = 0) -> Any? { | |
var res: Any? = nil | |
var finish = false | |
var count = 0, maxCount = Int(timeout * 10) // 0.1秒为间隔 | |
evaluateJavaScript(js) { (result, error) in | |
res = result | |
finish = true | |
} | |
while !finish { | |
RunLoop.current.run(until: Date(timeIntervalSinceNow: 0.1)) | |
if maxCount > 0 && count >= maxCount { | |
finish = true | |
} | |
count += 1 | |
} | |
return res | |
} | |
} | |
enum URLType { | |
case about | |
case http // 普通的 http(s) | |
case appStore | |
case map | |
case custom // 例如 weiyun://, txent: | |
} | |
extension URLComponents { | |
var type: URLType { | |
let s = scheme?.lowercased() | |
if s == "http" || s == "https" { | |
let h = host?.lowercased() | |
if h == "itunes.apple.com" { // 居然不是 Universal Link,亮瞎 | |
return .appStore | |
} | |
if h == "maps.apple.com" && query != nil { | |
return .map | |
} | |
return .http | |
} | |
if s == "about" { | |
return .about | |
} | |
return .custom | |
} | |
} | |
// MARK: - WKNavigationDelegate | |
func webView(_ wv: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { | |
guard let url = navigationAction.request.url, let uc = URLComponents(url: url, resolvingAgainstBaseURL: true), let _ = uc.scheme else { | |
print("这个request不正常\(navigationAction.request)") | |
decisionHandler(.cancel) | |
return | |
} | |
handleURL(url, decisionHandler: decisionHandler) | |
} | |
func handleURL(_ url: URL, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { | |
// url 可能是 about:blank,即 navigationAction.targetFrame == nil,亦即 target="_blank" | |
// 典型例子:“软件许可及服务协议”跳转到“微信公众平台服务协议”后再跳转时 | |
guard let uc = URLComponents.init(url: url, resolvingAgainstBaseURL: true) else { | |
decisionHandler(.cancel) | |
return | |
} | |
let t = uc.type | |
switch t { | |
case .http: | |
handleHttpURL(url, decisionHandler: decisionHandler) | |
case .about: | |
decisionHandler(.allow) | |
case .appStore, .map: | |
decisionHandler(.cancel) | |
// 保持跟微信的体验一致 | |
let appName = t == .appStore ? "App Store" : "地图" | |
let ac = UIAlertController(title: nil, message: "将会离开\"\(Global.displayName)\"\n并跳转到\(appName)", preferredStyle: .alert) | |
ac.addAction(UIAlertAction(title: "取消", style: .cancel)) | |
ac.addAction(UIAlertAction(title: "确定", style: .default, handler: { (aa) in | |
UIApplication.shared.openURL(url) | |
log.i("open application with url: \(url)") | |
})) | |
present(ac, animated: true, completion: nil) | |
case .custom: | |
decisionHandler(.cancel) | |
handleCustomURL(url) | |
} | |
} | |
/// Can be override | |
/// 需识别 universal link | |
func handleHttpURL(_ url: URL, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { | |
decisionHandler(.allow) | |
} | |
/// Can be override | |
func handleCustomURL(_ url: URL) { | |
if #available(iOS 10, *) { | |
UIApplication.shared.open(url, options: [:], completionHandler: nil) | |
} else { | |
UIApplication.shared.openURL(url) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment