I am trying to capture the downloading of a zip file from a WKWebView in iOS. After logging in, going to this link, requesting the archive and clicking the download button, the zip file is not downloaded. However, the WKWebView does display the file in the web browser, or appears to do so (see screenshots below). When trying to download the file from the web view, I'm only pulling an HTML file.
Can someone provide some direction here, regarding the right approach to catch and download the zip file? NOTE, the zip file has no direct link. Code for the WKWebView delegate method, and the Download Handler below.
webView didFinishNavigation
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
NSURLComponents *comps = [[NSURLComponents alloc] initWithURL:webView.URL
resolvingAgainstBaseURL:NO];
comps.query = nil;
NSLog(@"did finish nav URL: %@", webView.URL);
if ([webView.URL.absoluteString isEqualToString:LI_DOWNLOAD_URL]) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[DownloadHandler downloadFileFromURL:webView.URL completion:^(NSString *filepath) {
NSLog(@"%@",filepath);
}];
});
}
else if ([comps.string isEqual: LI_REDIRECT_CATCH1] ||
[comps.string isEqual: LI_REDIRECT_CATCH2] ||
[comps.string isEqual: LI_REDIRECT_CATCH3]) {
self.statusText.text = @"Tap the \"Sign In\" button to log into LinkedIn";
}
else if ([comps.string isEqual: LI_EXPORT_PAGE]) {
NSString *javascript = @"javascript:" \
"var reqBtn = document.getElementById('request-button');" \
"var pndBtn = document.getElementById('pending-button');" \
"var dwnBtn = document.getElementById('download-button');" \
"if (reqBtn) {" \
" window.scrollTo(reqBtn.offsetLeft, 0);" \
" window.webkit.messageHandlers.dataExport.postMessage('willRequestData');" \
" reqBtn.addEventListener('click', function() {" \
" window.webkit.messageHandlers.dataExport.postMessage('didRequestData');" \
" }, false);" \
"} else if (pndBtn) {" \
" window.scrollTo(pndBtn.offsetLeft, 0);" \
" window.webkit.messageHandlers.dataExport.postMessage('isRequestPending');" \
"} else if (dwnBtn) {" \
" window.scrollTo(dwnBtn.offsetLeft, 0);" \
" window.webkit.messageHandlers.dataExport.postMessage('willDownloadData');" \
" dwnBtn.onclick = function() {" \
" window.webkit.messageHandlers.dataExport.postMessage('didDownloadData');" \
" };" \
"}";
[self.webView evaluateJavaScript:javascript completionHandler:nil];
}
}
Download Handler
+ (void)downloadFileFromURL:(NSURL *)url completion:(void (^)(NSString *filepath))completion {
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (!error) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"linkedin-file-export.zip"];
[data writeToFile:dataPath atomically:YES];
completion(dataPath);
});
}
else {
NSLog(@"%@",error);
completion([NSString string]);
}
}];
[postDataTask resume];
}
I have tried this through using a UIWebView as well, and am getting the same result. In Android, this can be accomplished with a download listener. I'd be open to an approach like this if its available, but I don't think it is in iOS.
Thanks for any help.