You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否用NSURLSessionDownloadTask获响应头后终止不必要的大文件下载?

解决方案:用NSURLSessionDownloadTask实现文件更新校验与提前中断

嗨,你完全可以用NSURLSessionDownloadTask来实现这个需求,没必要换成NSURLSessionDataTask,而且确实能在获取响应头、开始下载数据前中断任务——核心是利用NSURLSession的代理方法拦截响应阶段的逻辑。

具体实现思路

关键在于NSURLSessionDownloadDelegate里的这个代理方法:

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler;

当下载任务收到服务器的响应头时,这个方法会被调用,此时还没有开始下载文件数据,这正是你需要的校验时机。

步骤拆解

  1. 提取并转换服务器的修改时间
    从响应头里拿到Last-Modified字段,将其转换为NSDate对象(注意HTTP标准时间格式的兼容处理):

    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
    NSString *lastModifiedStr = httpResponse.allHeaderFields[@"Last-Modified"];
    
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
    formatter.dateFormat = @"EEE, dd MMM yyyy HH:mm:ss zzz";
    NSDate *serverModifiedDate = [formatter dateFromString:lastModifiedStr];
    
  2. 对比本地时间戳,决定是否终止下载
    把转换后的服务器时间和你本地保存的时间戳对比,根据结果处理任务:

    NSDate *localSavedDate = // 从本地取出之前保存的文件修改时间戳
    
    if ([serverModifiedDate compare:localSavedDate] != NSOrderedDescending) {
        // 文件没有更新,终止任务
        completionHandler(NSURLSessionResponseCancel);
        // 保险起见可额外调用cancel,不过传Cancel参数后任务会自动终止
        [downloadTask cancel];
    } else {
        // 文件有更新,继续下载
        completionHandler(NSURLSessionResponseAllow);
    }
    

关键说明

  • 无需切换到DataTask:DownloadTask专门针对大文件下载做了优化(比如断点续存、后台下载),完全适配你的场景,不用额外换用DataTask。
  • 中断时机精准:didReceiveResponse方法触发时仅收到响应头,还未开始接收文件数据,此时中断不会产生无用的下载流量。
  • 注意时间格式兼容:不同服务器返回的Last-Modified格式可能略有差异,用en_US_POSIX locale可以避免时区和语言格式问题。

内容的提问来源于stack exchange,提问作者darvin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:22:51