fie*_*edl 5 ios swift wkwebview
在a中WKWebView,当用户单击引用某些文件类型的链接(例如,联系人的VCF文件或日历事件的ICS文件)时,我想截取该链接,即取消导航,而是显示内容使用专门的视图控制器.
例如,CNContactViewController可用于显示联系人,EKEventViewController可用于显示日历事件.
我可以通过分配WKNavigationDelegate和使用来拦截点击decidePolicyForNavigationAction:
// Swift 2
extension MyController: WKNavigationDelegate {
func webView(webView: WKWebView, decidePolicyForNavigationAction
navigationAction: WKNavigationAction,
decisionHandler: (WKNavigationActionPolicy) -> ()) {
let url = navigationAction.request.URL!
if url.pathExtension == "ics" {
decisionHandler(WKNavigationActionPolicy.Cancel)
// TODO: download data
// TODO: display with EKEventViewController
} else if url.pathExtension == "vcf" {
decisionHandler(WKNavigationActionPolicy.Cancel)
// TODO: download data
// TODO: display with CNContactViewController
} else {
decisionHandler(WKNavigationActionPolicy.Allow)
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是为了显示专用控制器的文件,我需要先从给定的数据中下载数据url.
我怎样才能做到这一点?
由于下载需要身份验证,因此下载需要与其共享cookie WKWebView,或使用其他技术来共享已经过身份验证的会话.
如果有帮助:我已经有访问网络视图的WKProcessPool和WKWebViewConfiguration.根据我的理解,cookie与某种程度上有关WKProcessPool.但我不知道如何使用它来下载内容,例如使用NSURLSession.
这感觉很hacky,但我通过执行WKWebView一些javascript来解决这个问题,该javascript通过ajax检索内容并将其返回到completionHandlerswift中。
支持WKWebView调用evaluateJavaScript,将 javascript 的结果传递给completionHandler:
Run Code Online (Sandbox Code Playgroud)func evaluateJavaScript(_ javaScriptString: String, completionHandler completionHandler: ((AnyObject?, NSError?) -> Void)?)
由于服务器端有jQuery ,我用它来发送ajax请求,如下所示。但是,当然,这也可以使用普通的 javascript 来完成。
(function(url) {
var result = '';
$.ajax({
type: 'GET',
url: url,
success: function(r) {result = r},
failure: function() {result = null},
async: false
});
return result
})(url)
Run Code Online (Sandbox Code Playgroud)
可以通过 swift 的字符串插值url传递给 javascript 。
WKWebView为了轻松使用它,我扩展了该类WKWebView。
// Views/WKWebView.swift
import WebKit
extension WKWebView {
func readUrlContent(url: NSURL, completionHandler: (result: String) -> Void) {
self.evaluateJavaScript("(function() { var result = ''; $.ajax({type: 'GET', url: '\(url)', success: function(r) {result = r}, failure: function() {result = null}, async: false }); return result })()", completionHandler: { (response, error) -> Void in
let result = response as! String
completionHandler(result: result)
})
}
}
Run Code Online (Sandbox Code Playgroud)
从问题的示例来看,可以这样调用:
let url = navigationAction.request.URL!
if url.pathExtension == "ics" {
decisionHandler(WKNavigationActionPolicy.Cancel)
webView.readUrlContent(url) { (result: String) in
print(result)
// TODO: display with EKEventViewController
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3595 次 |
| 最近记录: |