Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I retrieve a file using WKWebView?

There is a file (CSV) that I want to download. It is behind a login screen on a website. I wanted to show a WKWebView to allow the user to log in and then have the app download the file after they had logged in.

I've tried downloading the file outside of WKWebView after the user has logged in to the website, but the session data seems to be sandboxed because it downloads an html document with the login form instead of the desired file.

I've also tried adding a WKUserScript to the WKUserContentController object, but the script doesn't get run when a non-HTML file is loaded.

Is there a way for me to access this file while allowing users to log in via the WKWebView?

like image 502
Devin McKaskle Avatar asked Jun 28 '14 06:06

Devin McKaskle


People also ask

How do I download files from WKWebView?

With func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { , you get the file url to download. Then download it with JS.

Does Chrome use WKWebView?

In Chrome 48 we've made the switch from UIWebView to WKWebView, leading to dramatic improvements in stability, speed, responsiveness, and web compatibility.

What is a WKWebView?

Overview. A WKWebView object is a platform-native view that you use to incorporate web content seamlessly into your app's UI. A web view supports a full web-browsing experience, and presents HTML, CSS, and JavaScript content alongside your app's native views.


2 Answers

Right now, WKWebView instances will ignore any of the default networking storages (NSURLCache, NSHTTPCookieStorage, NSCredentialStorage) and also the standard networking classes you can use to customize the network requests (NSURLProtocol, etc.).

So the cookies of the WKWebView instance are not stored in the standard Cookie storage of your App, and so NSURLSession/NSURLConnection which only uses the standard Cookie storage has no access to the cookies of WKWebView (and exactly this is probably the problem you have: the „login status“ is most likely stored in a cookie, but NSURLSession/NSURLConnection won’t see the cookie).

The same is the case for the cache, for the credentials etc. WKWebView has its own private storages and therefore does not play well with the standard Cocoa networking classes.

You also can’t customize the requests (add your own custom HTTP headers, modify existing headers, etc), use your own custom URL schemes etc, because also NSURLProtocol is not supported by WKWebView.

So right now WKWebView is pretty useless for many Apps, because it does not participate with the standard networking APIs of Cocoa.

I still hope that Apple will change this until iOS 8 gets released, because otherwise WKWebView will be useless for many Apps, and we are probably stick with UIWebView a little bit longer.

So send bug reports to Apple, so Apple gets to know that these issues are serious and needs to be fixed.

like image 89
Alex Avatar answered Sep 23 '22 23:09

Alex


Have you checked the response cookies coming back from the request. You could use a delegate method like this.

- (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); } 
like image 26
Nick Anger Avatar answered Sep 21 '22 23:09

Nick Anger