-
Notifications
You must be signed in to change notification settings - Fork 6
RMET-5110 ::: added fix do allow open url InAppBrowser and download a file #46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,6 +19,12 @@ class OSIABWebViewModel: NSObject, ObservableObject { | |
|
|
||
| /// Indicates if first load is already done. This is important in order to trigger the `browserPageLoad` event. | ||
| private var firstLoadDone: Bool = false | ||
| /// Indicates if a download is in progress, to suppress navigation errors caused by download redirects. | ||
| private var isDownloadInProgress: Bool = false | ||
| /// Retains the active WKDownload to prevent it from being deallocated mid-download. | ||
| private var activeDownload: AnyObject? | ||
| /// Stores the destination URL for the active download. | ||
| private var downloadDestinationURL: URL? | ||
|
|
||
| /// Custom headers to be used by the WebView. | ||
| private let customHeaders: [String: String]? | ||
|
|
@@ -206,6 +212,18 @@ extension OSIABWebViewModel: WKNavigationDelegate { | |
| } | ||
| } | ||
|
|
||
| @available(iOS 14.5, *) | ||
| func webView(_ webView: WKWebView, navigationAction: WKNavigationAction, didBecome download: WKDownload) { | ||
| download.delegate = self | ||
| } | ||
|
|
||
| @available(iOS 14.5, *) | ||
| func webView(_ webView: WKWebView, navigationResponse: WKNavigationResponse, didBecome download: WKDownload) { | ||
| isDownloadInProgress = true | ||
| activeDownload = download | ||
| download.delegate = self | ||
| } | ||
|
|
||
| func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { | ||
| if !firstLoadDone { | ||
| callbackHandler.onBrowserPageLoad() | ||
|
|
@@ -225,13 +243,69 @@ extension OSIABWebViewModel: WKNavigationDelegate { | |
| } | ||
|
|
||
| private func handleWebViewNavigationError(_ delegateName: String, error: Error) { | ||
| print("webView: \(delegateName) - \(error.localizedDescription)") | ||
| if (error as NSError).code != NSURLErrorCancelled { | ||
| let nsError = error as NSError | ||
| if isDownloadInProgress && nsError.code == 102 { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we replace the magic number 102 with a named constant or add a comment explaining its purpose? |
||
| isDownloadInProgress = false | ||
| return | ||
| } | ||
| if nsError.code != NSURLErrorCancelled { | ||
| self.error = error | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // MARK: - WKNavigationDelegate (response) implementation | ||
| extension OSIABWebViewModel { | ||
| func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) { | ||
| if navigationResponse.canShowMIMEType { | ||
| decisionHandler(.allow) | ||
| } else { | ||
| if #available(iOS 14.5, *) { | ||
| decisionHandler(.download) | ||
| } else { | ||
| decisionHandler(.cancel) | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // MARK: - WKDownloadDelegate implementation | ||
| @available(iOS 14.5, *) | ||
| extension OSIABWebViewModel: WKDownloadDelegate { | ||
|
|
||
| func download(_ download: WKDownload, decideDestinationUsing response: URLResponse, suggestedFilename: String, completionHandler: @escaping (URL?) -> Void) { | ||
| let tempDir = FileManager.default.temporaryDirectory | ||
| let fileURL = tempDir.appendingPathComponent(suggestedFilename) | ||
| if FileManager.default.fileExists(atPath: fileURL.path) { | ||
| try? FileManager.default.removeItem(at: fileURL) | ||
| } | ||
| downloadDestinationURL = fileURL | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we clean up the downloaded files at some point? |
||
| completionHandler(fileURL) | ||
| } | ||
|
|
||
| func downloadDidFinish(_ download: WKDownload) { | ||
| guard let fileURL = downloadDestinationURL else { return } | ||
| activeDownload = nil | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we update the isDownloadInProgress property here? Currently, it is only set to false when an error occurs. |
||
| DispatchQueue.main.async { | ||
| let activityVC = UIActivityViewController(activityItems: [fileURL], applicationActivities: nil) | ||
| if let rootVC = UIApplication.shared.connectedScenes | ||
| .compactMap({ $0 as? UIWindowScene }) | ||
| .flatMap({ $0.windows }) | ||
| .first(where: { $0.isKeyWindow })?.rootViewController { | ||
| var topVC = rootVC | ||
| while let presented = topVC.presentedViewController { | ||
| topVC = presented | ||
| } | ||
| topVC.present(activityVC, animated: true) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| func download(_ download: WKDownload, didFailWithError error: Error, resumeData: Data?) { | ||
| activeDownload = nil | ||
| } | ||
| } | ||
|
|
||
| // MARK: - WKUIDelegate implementation | ||
| extension OSIABWebViewModel: WKUIDelegate { | ||
| typealias ButtonHandler = (UIAlertController) -> Void | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way these variables are declared suggests that only one download can be in progress at a time. Is it guaranteed that multiple simultaneous downloads can never occur?