File Downloads
Extended WebView with .ics File Download Handling
WebView with .ics File Download Handlingimport SwiftUI
import WebKit
struct WebView: UIViewRepresentable {
// Define the specific UIView subclass we are representing
typealias UIViewType = WKWebView
let urlString: String
func makeUIView(context: Context) -> WKWebView {
// ... shortened ...
}
func updateUIView(_ webView: WKWebView, context: Context) {
// ... shortened ...
}
func makeCoordinator() -> Coordinator {
Coordinator()
}
// Coordinator
// Handles callbacks from the WKWebView
class Coordinator: NSObject, WKScriptMessageHandler, WKNavigationDelegate, WKUIDelegate {
// Reference back to the SwiftUI view
var parent: WebView
// Weak reference maybe better if lifecycle allows?
var webView: WKWebView?
init(_ parent: WebView) {
self.parent = parent
}
// WKScriptMessageHandler
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "MessageFromLiSA" {
// Handle message from JavaScript
print("Received message from LiSA: \(message.body)")
// You could trigger actions in your SwiftUI view here if needed,
// e.g., using @State variables passed down or Combine publishers.
}
}
// Handle navigation actions that become downloads
func webView(_ webView: WKWebView, navigationAction: WKNavigationAction, didBecome download: WKDownload) {
download.delegate = self
print("Download started for: \(navigationAction.request.url?.absoluteString ?? "Unknown URL")")
}
// File download in progress
func download(_ download: WKDownload, didReceive response: URLResponse) {
print("Downloading: \(response.suggestedFilename ?? "Unknown filename")")
}
// Handle file download completion
func download(_ download: WKDownload, didFinishWith location: URL) {
guard let suggestedFilename = download.response?.suggestedFilename else {
print("Unable to retrieve filename")
return
}
let fileManager = FileManager.default
let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
let destinationURL = documentsDirectory.appendingPathComponent(suggestedFilename)
do {
// Move the file to a permanent location
try fileManager.moveItem(at: location, to: destinationURL)
print("File saved to: \(destinationURL)")
// Present options to open the `.ics` file
DispatchQueue.main.async {
let activityViewController = UIActivityViewController(activityItems: [destinationURL], applicationActivities: nil)
if let topController = UIApplication.shared.windows.first?.rootViewController {
topController.present(activityViewController, animated: true, completion: nil)
}
}
} catch {
print("Error saving file: \(error.localizedDescription)")
}
}
// Handle errors during file download
func download(_ download: WKDownload, didFailWithError error: Error, resumeData: Data?) {
print("Download failed: \(error.localizedDescription)")
}
}
}Key Changes and Additions
Last updated