
本文档旨在指导开发者如何在 iOS 应用中使用 WKWebView 下载由 PHP 脚本动态生成的文件。针对 iOS 14.5 及以上版本,我们将介绍利用 WKDownloadDelegate 实现下载并指定保存路径的方法。对于更早的 iOS 版本,则提供手动下载数据并保存的替代方案。
iOS 14.5 及以上版本:使用 WKDownloadDelegate
自 iOS 14.5 起,苹果引入了 WKDownloadDelegate,使得在 WKWebView 中处理文件下载变得更加方便。通过实现该代理,我们可以拦截下载请求,并指定文件的保存路径。
以下是一个完整的示例,展示了如何使用 WKDownloadDelegate 下载 PHP 生成的文件:
#import@interface ViewController : UIViewController @property (nonatomic, strong) WKWebView *webView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds]; self.webView.navigationDelegate = self; NSURL* url = [NSURL URLWithString: @"https://your-domain.com/download.php"]; NSURLRequest* request = [NSURLRequest requestWithURL: url]; [self.webView loadRequest:request]; [self.view addSubview:self.webView]; } #pragma mark - WKNavigationDelegate - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(nonnull WKNavigationResponse *)navigationResponse decisionHandler:(nonnull void (^)(WKNavigationResponsePolicy))decisionHandler { if (navigationResponse.canShowMIMEType) { decisionHandler(WKNavigationResponsePolicyAllow); } else { decisionHandler(WKNavigationResponsePolicyDownload); } } - (void)webView:(WKWebView *)webView navigationResponse:(WKNavigationResponse *)navigationResponse didBecomeDownload:(WKDownload *)download { download.delegate = self; } #pragma mark - WKDownloadDelegate - (void)download:(WKDownload *)download decideDestinationUsingResponse:(NSURLResponse *)response suggestedFilename:(NSString *)suggestedFilename completionHandler:(void (^)(NSURL * _Nullable))completionHandler { // 保存到 Documents 目录 NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSString *filePath = [documentPath stringByAppendingPathComponent:suggestedFilename]; NSURL* url = [NSURL fileURLWithPath:filePath]; completionHandler(url); } - (void)downloadDidFinish:(WKDownload *)download { // 下载完成 NSLog(@"Download finished"); } - (void)download:(WKDownload *)download didFailWithError:(NSError *)error resumeData:(NSData *)resumeData { // 下载失败 NSLog(@"Download failed with error: %@", error); } @end
代码解释:
立即学习“PHP免费学习笔记(深入)”;
-
导入 WebKit: 引入必要的头文件
. - 创建 WKWebView: 创建一个 WKWebView 实例,并设置其 navigationDelegate 为当前 ViewController。
- 加载 URL: 使用 loadRequest: 方法加载 PHP 脚本的 URL。
- decidePolicyForNavigationResponse:: 此方法判断是否允许导航响应。 如果 navigationResponse.canShowMIMEType 为真,则允许在 WebView 中显示内容。 否则,设置为 WKNavigationResponsePolicyDownload,表示这是一个下载请求。
- navigationResponse:didBecomeDownload:: 此方法在导航响应变成下载时被调用,设置 download.delegate 为当前 ViewController。
- download:decideDestinationUsingResponse:suggestedFilename:completionHandler:: 这是 WKDownloadDelegate 的核心方法。 在下载开始前,系统会调用此方法来确定下载文件的保存路径。 我们在此方法中获取 Documents 目录,并将文件名拼接成完整的路径,然后通过 completionHandler 将路径传递给系统。
- downloadDidFinish:: 下载完成时调用。
- download:didFailWithError:resumeData:: 下载失败时调用。
注意事项:
seo特别版程序介绍:注意:普通用户建议使用淄博分类信息港程序普通版本。主要针对seo需要增加了自定义功能:自定义文件路径;自定义文件名;自定义关键字。这些功能的作用,只有自己体会了。以下是淄博分类信息港程序的介绍:淄博分类信息港程序一套现成的城市分类信息网站发布系统。发布管理房屋、人才、招租、招聘、求购、求租、搬迁、运输、二手交易、招生培训、婚介交友等各类信息的发布和查询。淄博分类信息港发布程序
- 确保你的 Info.plist 文件中允许 App Transport Security (ATS) 豁免,以便允许加载非 HTTPS 的 URL (仅在开发阶段建议)。
- suggestedFilename 可能为空,需要进行处理,例如生成一个随机文件名。
- 需要处理下载失败的情况,并提供友好的错误提示。
iOS 14.5 之前版本:手动下载数据
对于 iOS 14.5 之前的版本,我们需要手动下载数据并保存到本地。 以下是一个示例:
#import@interface ViewController : UIViewController @property (nonatomic, strong) WKWebView *webView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds]; self.webView.navigationDelegate = self; NSURL* url = [NSURL URLWithString: @"https://your-domain.com/download.php"]; NSURLRequest* request = [NSURLRequest requestWithURL: url]; [self.webView loadRequest:request]; [self.view addSubview:self.webView]; } #pragma mark - WKNavigationDelegate - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(nonnull WKNavigationResponse *)navigationResponse decisionHandler:(nonnull void (^)(WKNavigationResponsePolicy))decisionHandler { if (navigationResponse.canShowMIMEType) { decisionHandler(WKNavigationResponsePolicyAllow); } else { NSURL* downloadUrl = navigationResponse.response.URL; NSURLSessionDataTask* dataTask = [NSURLSession.sharedSession dataTaskWithURL:downloadUrl completionHandler:^(NSData* data, NSURLResponse* response, NSError* error) { if (data != nil) { // 保存到 Documents 目录 NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSString *filePath = [documentPath stringByAppendingPathComponent:response.suggestedFilename]; [data writeToFile:filePath atomically:YES]; NSLog(@"File downloaded to: %@", filePath); } else { NSLog(@"Download failed with error: %@", error); } }]; [dataTask resume]; decisionHandler(WKNavigationResponsePolicyCancel); } } @end
代码解释:
立即学习“PHP免费学习笔记(深入)”;
- decidePolicyForNavigationResponse:: 与 iOS 14.5 及以上版本的实现类似,判断是否允许导航响应。
- 创建 NSURLSessionDataTask: 如果确定是下载请求,则创建一个 NSURLSessionDataTask 来下载文件。
- 下载数据: 在 completionHandler 中,将下载的数据保存到 Documents 目录。
- 取消导航: 使用 decisionHandler(WKNavigationResponsePolicyCancel) 取消 WebView 的导航,因为我们已经手动处理了下载。
注意事项:
- 与 iOS 14.5 及以上版本类似,需要处理 suggestedFilename 为空的情况。
- 需要处理下载失败的情况,并提供友好的错误提示。
- 此方法在主线程中执行,如果下载的文件较大,可能会阻塞 UI。 可以考虑使用 GCD 将下载操作放到后台线程执行。
总结
本文档提供了两种在 WKWebView 中下载 PHP 生成文件的方法,分别适用于 iOS 14.5 及以上版本和之前的版本。 使用 WKDownloadDelegate 可以更方便地管理下载过程,而手动下载数据则提供了对旧版本 iOS 的兼容性。 在实际开发中,应根据目标 iOS 版本选择合适的方法,并注意处理各种异常情况,以提供良好的用户体验。










