能否用NSURLSessionDownloadTask获响应头后终止不必要的大文件下载?
解决方案:用NSURLSessionDownloadTask实现文件更新校验与提前中断
嗨,你完全可以用NSURLSessionDownloadTask来实现这个需求,没必要换成NSURLSessionDataTask,而且确实能在获取响应头、开始下载数据前中断任务——核心是利用NSURLSession的代理方法拦截响应阶段的逻辑。
具体实现思路
关键在于NSURLSessionDownloadDelegate里的这个代理方法:
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler;
当下载任务收到服务器的响应头时,这个方法会被调用,此时还没有开始下载文件数据,这正是你需要的校验时机。
步骤拆解
提取并转换服务器的修改时间
从响应头里拿到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];对比本地时间戳,决定是否终止下载
把转换后的服务器时间和你本地保存的时间戳对比,根据结果处理任务:NSDate *localSavedDate = // 从本地取出之前保存的文件修改时间戳 if ([serverModifiedDate compare:localSavedDate] != NSOrderedDescending) { // 文件没有更新,终止任务 completionHandler(NSURLSessionResponseCancel); // 保险起见可额外调用cancel,不过传Cancel参数后任务会自动终止 [downloadTask cancel]; } else { // 文件有更新,继续下载 completionHandler(NSURLSessionResponseAllow); }
关键说明
- 无需切换到DataTask:DownloadTask专门针对大文件下载做了优化(比如断点续存、后台下载),完全适配你的场景,不用额外换用DataTask。
- 中断时机精准:
didReceiveResponse方法触发时仅收到响应头,还未开始接收文件数据,此时中断不会产生无用的下载流量。 - 注意时间格式兼容:不同服务器返回的
Last-Modified格式可能略有差异,用en_US_POSIXlocale可以避免时区和语言格式问题。
内容的提问来源于stack exchange,提问作者darvin
相关产品推荐
相关产品推荐

