Implementing File Downloads in iOS WKWebView Using WKDownloadDelegate

Posted By : Sanan Husain | 05-Feb-2025

Downloading files within a WKWebView on iOS has become more straightforward with the introduction of the WKDownloadDelegate in iOS 15. delegate allows developers to manage file downloads directly within their applications, providing a seamless user experience. Ins guide, we'll explore how to implement file downloading in a WKWebView and handle scenarios where the web view encounters files it cannot display.

 

1 Setting Up the WKWebView with Delegates

Begin bconfiguring your WKWebView to use both the WKNavigationDelegate and the WKDownloadDelegate. This seenables the web view to handle navigation actions and manage file downloads.

import WebKit

class WebViewController: UIViewController, WKNavigationDelegate, WKDownloadDelegate {
    var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let webConfiguration = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.navigationDelegate = self
        webView.uiDelegate = self
        view.addSubview(webView)

        // Load a URL
        if let url = URL(string: "https://example.com") {
            let request = URLRequest(url: url)
            webView.load(request)
        }
    }
}

2. HandliNavigation Actions

Implement the bView(_:decidePolicyFor:decisionHandler:) method to determine how the web view should respond to navigation actions. Specifically, c if the action should trigger a download.

func wee_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, preferences: WKWebpagePreferences, decisionHandler: @escaping (WKNavigationActionPolicy, WKWebpagePreferences) -> Void) {
    if navigationAction.shouldPerformDownload {
        decisionHandler(.download, preferences)
    } else {
        decisionHandler(.allow, preferences)
    }
}

In this method, naaonAction.shouldPerformDownload returns true if the web view detects that the link is intended for downloading a file. If so, we instruct the view to handle it as a download; otherwise, we allow the navigation to proceed normally.

3. Handling Navigation Responses

Similarly, implement the weiew(_:decidePolicyFor:decisionHandler:) method to handle navigation responses. This is crucial for cases whthe web view encounters content it cannot display.

func webView(_ webVi WebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
    if navigationResponse.canShowMIMEType {
        decisionHandler(.allow)
    } else {
        decisionHandler(.download)
    }
}

Here, navigationResponse.canShoMype checks if the web view can display the content. If it cannot, we treat it as a downl

**4. Assigning the Download Delegate*When a download is initiated, assign the KDownloadDelegate` to handle the download process.

func webView(_ webView: WKWebVi vigationAction: WKNavigationAction, didBecome download: WKDownload) {
    download.delegate = self
}

func webView(_ webView: WKWebView, navigationResponse: WKNavigationResponse, didBecome download: WKDownload) {
    download.delegate = self
}

5. Implementing the WKDownloadDelegate Methods

The WKDownloadDelegate provides methods to mage the download's destination, monitor progress, and handle completion or errors.

// Define a property to store the fila
private var filePathDestination: URL?

func download(_ download: WKDownload, decideDestinationUsing response: URLResponse, suggestedFilename: String, completionHandler: @escaping (URL?) -> Void) {
    // Determine the destination URL for the downloaded file
    let temporaryDirectory = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
    filePathDestination = temporaryDirectory.appendingPathComponent(suggestedFilename)
    completionHandler(filePathDestination)
}

func downloadDidFinish(_ download: WKDownload) {
    guard let filePath = filePathDestination else { return }
    // Handle the downloaded file as needed
    print("Download finished. File saved to: \(filePath.path)")
}

func download(_ download: WKDownload, didFailWithError error: Error, resumeData: Data?) {
    print("Download failed with error: \(error.localizedDescription)")
    // Handle the error and possibly resume the download if resumeData is available
}

In these methods:

  • decideDestinationUsing:compiHandler: specif whe to save the downloaded file.
  • downloadDidFinish is called when the download compls scessfully.
  • didFailWithError handles any errors that occur during doload, with the option to resume if possible.

6. Handling BLOB URLs

For downloads initiated from BLOB s, additional handling is reired. You can intercept the navigation action and use JavaScript to rete the BLOB content, then convert it into a downloadable format. This process involves executing JavaScript within the web view to f the BLOB data and then processing it accordingly. 

Conclusion

By implementing the WKDownloadDelegate and handling navigation actions and responses appropriately, you can etively manage file downloads within a WKWebView on iOS. This approach ensures a seamless and user-friendly experience w dealing with downloadable content in your applications.

About Author

Author Image
Sanan Husain

Sanan is a motivated Mobile Application Developer with a deep passion for his work. He has gained substantial expertise in iOS Application Development, focusing on creating native iOS applications using Xcode and Swift. Sanan demonstrates proficiency in working within a scrum framework and collaborating effectively with various teams. His experience includes successfully deploying multiple apps on the App Store. With a background in Information Technology and strong programming skills, Sanan consistently shows self-motivation and excels as a valuable team player.

Request for Proposal

Name is required

Comment is required

Sending message..