@@ -1401,6 +1401,12 @@ - (void) webView:(WKWebView *)webView
14011401 decisionHandler (WKNavigationActionPolicyCancel );
14021402 return ;
14031403 }
1404+ } else if ([self isDownloadableFileURL: navigationAction.request.URL]) {
1405+ if (_onFileDownload) {
1406+ [self handleRegularFileDownload: urlString];
1407+ decisionHandler (WKNavigationActionPolicyCancel );
1408+ return ;
1409+ }
14041410 }
14051411
14061412 dispatch_once (&onceToken, ^{
@@ -2053,6 +2059,50 @@ - (void)handleBlobDownloadUrl:(NSString *)urlString {
20532059 [self .webView evaluateJavaScript: jsCode completionHandler: ^(id result, NSError *error) {}];
20542060}
20552061
2062+ - (BOOL )isDownloadableFileURL: (NSURL *)url {
2063+ if (!url || !url.pathExtension ) {
2064+ return NO ;
2065+ }
2066+
2067+ NSString *extension = [url.pathExtension lowercaseString ];
2068+ NSSet *downloadableExtensions = [NSSet setWithObjects:
2069+ @" jpg" , @" jpeg" , @" png" , @" gif" , @" bmp" , @" webp" , @" svg" , // Images
2070+ @" pdf" , @" doc" , @" docx" , @" xls" , @" xlsx" , @" ppt" , @" pptx" , // Documents
2071+ @" txt" , @" rtf" , @" csv" , @" json" , @" xml" , // Text files
2072+ @" zip" , @" rar" , @" 7z" , @" tar" , @" gz" , // Archives
2073+ @" mp3" , @" wav" , @" m4a" , @" aac" , @" flac" , // Audio
2074+ @" mp4" , @" avi" , @" mov" , @" wmv" , @" mkv" , @" webm" , // Video
2075+ nil
2076+ ];
2077+
2078+ return [downloadableExtensions containsObject: extension];
2079+ }
2080+
2081+ - (void )handleRegularFileDownload: (NSString *)urlString {
2082+ NSString *jsCode = [NSString stringWithFormat:
2083+ @" fetch('%@ ')"
2084+ " .then(response => {"
2085+ " if (!response.ok) throw new Error('Unable to download file');"
2086+ " return response.blob();"
2087+ " })"
2088+ " .then(blob => {"
2089+ " const reader = new FileReader();"
2090+ " reader.onloadend = function() {"
2091+ " window.webkit.messageHandlers.base64Handler.postMessage(reader.result);"
2092+ " };"
2093+ " reader.readAsDataURL(blob);"
2094+ " })"
2095+ " .catch(error => {"
2096+ " console.error('Download failed:', error);"
2097+ " });" , urlString];
2098+
2099+ [self .webView evaluateJavaScript: jsCode completionHandler: ^(id result, NSError *error) {
2100+ if (error) {
2101+ NSLog (@" Error downloading file: %@ " , error.localizedDescription );
2102+ }
2103+ }];
2104+ }
2105+
20562106@end
20572107
20582108@implementation RNCWeakScriptMessageDelegate
0 commit comments