-
-
Save kushwaha03/1c2c39dbc542189ac1dc4d777bf44205 to your computer and use it in GitHub Desktop.
This file contains 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
import UIKit | |
import WebKit | |
struct MimeType { | |
var type:String | |
var fileExtension:String | |
} | |
class WebViewController: UIViewController { | |
@IBOutlet weak var webView: WKWebView! | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
} | |
} | |
@available(iOS 14.5, *) | |
extension WebViewController: WKDownloadDelegate, WKNavigationDelegate { | |
//WKNavigationDelegate | |
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { | |
print("Error is::: ",error.localizedDescription) | |
} | |
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) { | |
print("Started Commiting") | |
} | |
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { | |
print("Started web load") | |
} | |
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) { | |
print("Error is::: ",error.localizedDescription) | |
} | |
//WKDownloadDelegate | |
func webView(_ webView: WKWebView, navigationResponse: WKNavigationResponse, didBecome download: WKDownload) { | |
download.delegate = self | |
} | |
func webView(_ webView: WKWebView, navigationAction: WKNavigationAction, didBecome download: WKDownload) { | |
download.delegate = self | |
} | |
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) { | |
if let mimeType = navigationResponse.response.mimeType { | |
if isMimeTypeConfigured(mimeType) { | |
if let url = navigationResponse.response.url { | |
if #available(iOS 14.5, *) { | |
decisionHandler(.download) | |
} else { | |
var fileName = getDefaultFileName(forMimeType: mimeType) | |
if let name = getFileNameFromResponse(navigationResponse.response) { | |
fileName = name | |
} | |
downloadData(fromURL: url, fileName: fileName) { success, destinationURL in | |
if success, let destinationURL = destinationURL { | |
self.openDownloadFile(destinationURL) } | |
} | |
decisionHandler(.cancel) | |
} | |
return | |
} | |
} | |
} | |
decisionHandler(.allow) | |
} | |
private func isMimeTypeConfigured(_ mimeType:String) -> Bool { | |
for record in self.mimeTypes { | |
if mimeType.contains(record.type) { | |
return true | |
} | |
} | |
return false | |
} | |
private func getDefaultFileName(forMimeType mimeType:String) -> String { | |
for record in self.mimeTypes { | |
if mimeType.contains(record.type) { | |
return "default." + record.fileExtension | |
} | |
} | |
return "default" | |
} | |
private func getFileNameFromResponse(_ response:URLResponse) -> String? { | |
if let httpResponse = response as? HTTPURLResponse { | |
let headers = httpResponse.allHeaderFields | |
if let disposition = headers["Content-Disposition"] as? String { | |
let components = disposition.components(separatedBy: " ") | |
if components.count > 1 { | |
let innerComponents = components[1].components(separatedBy: "=") | |
if innerComponents.count > 1 { | |
if innerComponents[0].contains("filename") { | |
return innerComponents[1] | |
} | |
} | |
} | |
} | |
} | |
return nil | |
} | |
private func downloadData(fromURL url: URL, | |
fileName: String, | |
completion: @escaping (Bool, URL?) -> Void) { | |
webView.configuration.websiteDataStore.httpCookieStore.getAllCookies { cookies in | |
let session = URLSession.shared | |
session.configuration.httpCookieStorage?.setCookies(cookies, for: url, mainDocumentURL: nil) | |
let task = session.downloadTask(with: url) { localURL, _, error in | |
if let localURL = localURL { | |
let destinationURL = self.moveDownloadedFile(url: localURL, fileName: fileName) | |
completion(true, destinationURL) | |
} else { | |
completion(false, nil) | |
} | |
} | |
task.resume() | |
} | |
} | |
private func moveDownloadedFile(url: URL, fileName: String) -> URL { | |
let tempDir = NSTemporaryDirectory() | |
let destinationPath = tempDir + fileName | |
let destinationURL = URL(fileURLWithPath: destinationPath) | |
try? FileManager.default.removeItem(at: destinationURL) | |
try? FileManager.default.moveItem(at: url, to: destinationURL) | |
return destinationURL | |
} | |
private func openDownloadFile(_ fileUrl: URL) { | |
DispatchQueue.main.async { | |
let controller = UIActivityViewController(activityItems: [fileUrl], applicationActivities: nil) | |
controller.popoverPresentationController?.sourceView = self.view | |
controller.popoverPresentationController?.sourceRect = self.view.frame | |
controller.popoverPresentationController?.barButtonItem = self.navigationItem.rightBarButtonItem | |
self.present(controller, animated: true, completion: nil) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment