正在下载文件 WKWebView ios
Downloading files WKWebView ios
我正在将我的应用程序从 UIWebView 迁移到 WKWebView。随着我对它进行更多的修改,一切都进展顺利并且工作正常。但是,我现在发现我无法下载论坛附件。
我正在使用 HCDownload,到目前为止对我来说一直是完美的,所以我知道它不是那一端。我相信这是要求,但我想不通。
我知道以下内容:
UIWebView => WKWebView Equivalent
--------------------------------------------------------------
didFailLoadWithError => didFailNavigation
webViewDidFinishLoad => didFinishNavigation
webViewDidStartLoad => didStartProvisionalNavigation
shouldStartLoadWithRequest => decidePolicyForNavigationAction
所以我正在尝试下面的已知内容:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURLRequest *request = navigationAction.request;
NSURL *fileURl = [request URL];
NSString *externalFileExtension = [fileURl pathExtension];
NSString *internalFileExtension = [[fileURl absoluteString] pathExtension];
HCDownloadViewController *dlvc = [[HCDownloadViewController alloc] init];
UINavigationController *vc = [[UINavigationController alloc] initWithRootViewController:dlvc];
dlvc.delegate = self;
vc.transitioningDelegate = self;
if (navigationAction.navigationType == WKNavigationTypeLinkActivated) {
//External file extensions
if ([fileExtensions containsObject:[externalFileExtension lowercaseString]]) {
[dlvc downloadURL:fileURl userInfo:nil];
[self presentViewController:vc animated:YES completion:nil];
[vc release];
NSLog(@"externalURL is %@", fileURl);
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
//Internal file links
if ([fileExtensions containsObject:[internalFileExtension lowercaseString]]) {
[self presentViewController:vc animated:YES completion:nil];
[dlvc downloadURL:fileURl userInfo:nil];
[vc release];
NSLog(@"internalURL is %@", fileURl);
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
}
它会通过找到文件扩展名来触发我的下载控制器,但它会下载 index.php,而不是文件。
示例url:
https://example.com/index.php?app=core&module=attach§ion=attach&attach_id=1234=example.zip;
我做错了什么。它之前在 UIWebView 中运行良好,我知道事情的完成方式有所不同。但是它怎么能从 say dropbox 下载东西就好了,但是论坛上的附件却搞砸了。
如有任何帮助,我们将不胜感激
您可能正在下载 not-authorized 页面,因为您的 WKWebView 和 HCDownload 实例不会像 UIWebView 那样共享 cookie 会话。这是 WK2 流程模型的速度和安全改进所必需的 trade-off。
我 added downloading 到我的 WKWebKit-based OSX/Swift mini-browser 通过实施 _WKDownloadDelegate。它是 El Cap 和 iOS9 的完全未记录的私有协议。它让您的导航委托调用 decisionHandler(_WKNavigationResponsePolicyBecomeDownload)
,WebKit 将在给您机会 pick/change 文件名后在后台下载。我还没有关于如何在 iOS 中实现文件选择器的最模糊的想法,也不知道 App Store 审阅者是否允许使用该协议。但我的应用程序现在可以正确处理从 session-authentication 网站(例如您的 PHP 论坛)的下载。
这就是我最终得到的结果,一切似乎都运行良好。
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
NSHTTPURLResponse *response = (NSHTTPURLResponse *)navigationResponse.response;
NSArray *cookies =[NSHTTPCookie cookiesWithResponseHeaderFields:[response allHeaderFields] forURL:response.URL];
for (NSHTTPCookie *cookie in cookies) {
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
}
decisionHandler(WKNavigationResponsePolicyAllow);
//NSLog(@"decidePolicyForNavigationResponse");
}
//Download manager
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURLRequest *request = navigationAction.request;
fileURL = request.URL;
HCDownloadViewController *dlvc = [[HCDownloadViewController alloc] init];
UINavigationController *vc = [[UINavigationController alloc] initWithRootViewController:dlvc];
vc.transitioningDelegate = self;
dlvc.delegate = self;
if (navigationAction.navigationType == WKNavigationTypeLinkActivated) {
//Internal file links
NSString *internalFileExtension = fileURL.absoluteString.pathExtension;
if ([fileExtensions containsObject:[internalFileExtension lowercaseString]]) {
//Fire download
[dlvc downloadURL:fileURL userInfo:nil];
[self presentViewController:vc animated:YES completion:nil];
[vc release];
NSLog(@"internalURL is %@", fileURL);
if (decisionHandler) {
decisionHandler(WKNavigationActionPolicyCancel);
}
return;
}
//External file extensions
NSString *externalFileExtension = fileURL.pathExtension;
if ([fileExtensions containsObject:[externalFileExtension lowercaseString]]) {
//Fire download
[dlvc downloadURL:fileURL userInfo:nil];
[self presentViewController:vc animated:YES completion:nil];
[vc release];
NSLog(@"externalURL is %@", fileURL);
if (decisionHandler) {
decisionHandler(WKNavigationActionPolicyCancel);
}
return;
}
}
if (decisionHandler) {
decisionHandler(WKNavigationActionPolicyAllow);
}
}
Swift 4:
ChrisOSX 的解决方案也解决了我的问题。登录该站点后,我正在尝试从该站点的 link 下载文档。我用过WKZombie to scrape the link, and then I wanted to download the file using Alamofire。我添加了这个
if let httpResponse = navigationResponse.response as? HTTPURLResponse, let url = httpResponse.url {
let allHeaders = httpResponse.allHeaderFields.reduce([String : String](), { (result, next) -> [String : String] in
guard let stringKey = next.key as? String, let stringValue = next.value as? String else { return result }
var buffer = result
buffer[stringKey] = stringValue
return buffer
})
let cookies = HTTPCookie.cookies(withResponseHeaderFields: allHeaders, for: url)
for cookie in cookies {
HTTPCookieStorage.shared.setCookie(cookie)
}
}
至:
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void)
在此之后,cookie 存储在共享 cookie 中,我可以使用 Alamofire 下载文件,而无需更改下载方法..
我正在将我的应用程序从 UIWebView 迁移到 WKWebView。随着我对它进行更多的修改,一切都进展顺利并且工作正常。但是,我现在发现我无法下载论坛附件。
我正在使用 HCDownload,到目前为止对我来说一直是完美的,所以我知道它不是那一端。我相信这是要求,但我想不通。
我知道以下内容:
UIWebView => WKWebView Equivalent
--------------------------------------------------------------
didFailLoadWithError => didFailNavigation
webViewDidFinishLoad => didFinishNavigation
webViewDidStartLoad => didStartProvisionalNavigation
shouldStartLoadWithRequest => decidePolicyForNavigationAction
所以我正在尝试下面的已知内容:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURLRequest *request = navigationAction.request;
NSURL *fileURl = [request URL];
NSString *externalFileExtension = [fileURl pathExtension];
NSString *internalFileExtension = [[fileURl absoluteString] pathExtension];
HCDownloadViewController *dlvc = [[HCDownloadViewController alloc] init];
UINavigationController *vc = [[UINavigationController alloc] initWithRootViewController:dlvc];
dlvc.delegate = self;
vc.transitioningDelegate = self;
if (navigationAction.navigationType == WKNavigationTypeLinkActivated) {
//External file extensions
if ([fileExtensions containsObject:[externalFileExtension lowercaseString]]) {
[dlvc downloadURL:fileURl userInfo:nil];
[self presentViewController:vc animated:YES completion:nil];
[vc release];
NSLog(@"externalURL is %@", fileURl);
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
//Internal file links
if ([fileExtensions containsObject:[internalFileExtension lowercaseString]]) {
[self presentViewController:vc animated:YES completion:nil];
[dlvc downloadURL:fileURl userInfo:nil];
[vc release];
NSLog(@"internalURL is %@", fileURl);
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
}
它会通过找到文件扩展名来触发我的下载控制器,但它会下载 index.php,而不是文件。
示例url:
https://example.com/index.php?app=core&module=attach§ion=attach&attach_id=1234=example.zip;
我做错了什么。它之前在 UIWebView 中运行良好,我知道事情的完成方式有所不同。但是它怎么能从 say dropbox 下载东西就好了,但是论坛上的附件却搞砸了。
如有任何帮助,我们将不胜感激
您可能正在下载 not-authorized 页面,因为您的 WKWebView 和 HCDownload 实例不会像 UIWebView 那样共享 cookie 会话。这是 WK2 流程模型的速度和安全改进所必需的 trade-off。
我 added downloading 到我的 WKWebKit-based OSX/Swift mini-browser 通过实施 _WKDownloadDelegate。它是 El Cap 和 iOS9 的完全未记录的私有协议。它让您的导航委托调用 decisionHandler(_WKNavigationResponsePolicyBecomeDownload)
,WebKit 将在给您机会 pick/change 文件名后在后台下载。我还没有关于如何在 iOS 中实现文件选择器的最模糊的想法,也不知道 App Store 审阅者是否允许使用该协议。但我的应用程序现在可以正确处理从 session-authentication 网站(例如您的 PHP 论坛)的下载。
这就是我最终得到的结果,一切似乎都运行良好。
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
NSHTTPURLResponse *response = (NSHTTPURLResponse *)navigationResponse.response;
NSArray *cookies =[NSHTTPCookie cookiesWithResponseHeaderFields:[response allHeaderFields] forURL:response.URL];
for (NSHTTPCookie *cookie in cookies) {
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
}
decisionHandler(WKNavigationResponsePolicyAllow);
//NSLog(@"decidePolicyForNavigationResponse");
}
//Download manager
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURLRequest *request = navigationAction.request;
fileURL = request.URL;
HCDownloadViewController *dlvc = [[HCDownloadViewController alloc] init];
UINavigationController *vc = [[UINavigationController alloc] initWithRootViewController:dlvc];
vc.transitioningDelegate = self;
dlvc.delegate = self;
if (navigationAction.navigationType == WKNavigationTypeLinkActivated) {
//Internal file links
NSString *internalFileExtension = fileURL.absoluteString.pathExtension;
if ([fileExtensions containsObject:[internalFileExtension lowercaseString]]) {
//Fire download
[dlvc downloadURL:fileURL userInfo:nil];
[self presentViewController:vc animated:YES completion:nil];
[vc release];
NSLog(@"internalURL is %@", fileURL);
if (decisionHandler) {
decisionHandler(WKNavigationActionPolicyCancel);
}
return;
}
//External file extensions
NSString *externalFileExtension = fileURL.pathExtension;
if ([fileExtensions containsObject:[externalFileExtension lowercaseString]]) {
//Fire download
[dlvc downloadURL:fileURL userInfo:nil];
[self presentViewController:vc animated:YES completion:nil];
[vc release];
NSLog(@"externalURL is %@", fileURL);
if (decisionHandler) {
decisionHandler(WKNavigationActionPolicyCancel);
}
return;
}
}
if (decisionHandler) {
decisionHandler(WKNavigationActionPolicyAllow);
}
}
Swift 4:
ChrisOSX 的解决方案也解决了我的问题。登录该站点后,我正在尝试从该站点的 link 下载文档。我用过WKZombie to scrape the link, and then I wanted to download the file using Alamofire。我添加了这个
if let httpResponse = navigationResponse.response as? HTTPURLResponse, let url = httpResponse.url {
let allHeaders = httpResponse.allHeaderFields.reduce([String : String](), { (result, next) -> [String : String] in
guard let stringKey = next.key as? String, let stringValue = next.value as? String else { return result }
var buffer = result
buffer[stringKey] = stringValue
return buffer
})
let cookies = HTTPCookie.cookies(withResponseHeaderFields: allHeaders, for: url)
for cookie in cookies {
HTTPCookieStorage.shared.setCookie(cookie)
}
}
至:
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void)
在此之后,cookie 存储在共享 cookie 中,我可以使用 Alamofire 下载文件,而无需更改下载方法..