iOS 设置下载部分文件,如何获取完整文件的大小

在视频的需求中,遇到这样一个需求,播放一视频的时候,要预下载

后面10条视频,但是只下载后面十条视频的前面1M

实现方法

1 创建请求时设置cacheLength

复制代码
    resource = [[IdiotResource alloc] init];
        resource.requestURL = task.requestURL;
        resource.requestOffset = task.requestOffset;
        resource.fileLength = task.fileLength;
        resource.cachePath = task.cachePath;
        //预先下载1M
        resource.cacheLength = 1024 * 1024;
        resource.resourceType = IdiotResourceTypeNet;//网络资源
        [self.resources addObject:resource];

二 创建请求时,设置 请求头的Range

复制代码
- (void)fetchFromNetwork:(IdiotResource *)task withResource:(IdiotResource *)resource{
    
    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[resource.requestURL originalSchemeURL] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10];
    if (resource.cacheLength > 0) {
        [request addValue:[NSString stringWithFormat:@"bytes=%lld-%lld", MAX(resource.requestOffset, task.requestOffset + task.cacheLength), resource.requestOffset+resource.cacheLength-1] forHTTPHeaderField:@"Range"];
    }else{
        [request addValue:[NSString stringWithFormat:@"bytes=%lld-", resource.requestOffset] forHTTPHeaderField:@"Range"];
    }
    NSURLSessionDataTask * datatask = [self.session dataTaskWithRequest:request];
    datatask.taskDescription = [NSString stringWithFormat:@"%lld",task.requestOffset];
    [datatask resume];
    
    self.currentDataTask = datatask;
}

三 如何获取完整文件的大小

在 - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {

代理方法里面

通过获取响应头的 Content-Range 字段来获取,注意,不能通过

Content-Length来获取,因为这个时候Content-Length 是我们设置的请求部分的大小,不是完整的大小

复制代码
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
    
    IdiotResource * task = [self.taskDic objectForKey:dataTask.taskDescription];
    
    if (task.cancel) return;
    
    if (task.fileLength <= 0) {
        NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *)response;
        NSString * contentRange = [[httpResponse allHeaderFields] objectForKey:@"Content-Range"];
        NSString * fileLength = [[contentRange componentsSeparatedByString:@"/"] lastObject];
        task.fileLength = fileLength.integerValue > 0 ? fileLength.integerValue : response.expectedContentLength;
    }
    
    if (self.currentResource.fileLength <= 0) {
        self.currentResource.fileLength = task.fileLength;
    }
    
    if (!task.cachePath.length) {
        task.cachePath = [IdiotFileManager createSliceWithUrl:task.requestURL sliceName:[NSString stringWithFormat:@"%lld-%lld",task.requestOffset,task.fileLength]];
    }
    
    if (self.currentResource.cacheLength <= 0) {
        self.currentResource.cacheLength = task.fileLength - task.requestOffset;
    }
    
    completionHandler(NSURLSessionResponseAllow);
}

如下图,所示

相关推荐
茶底世界之下4 天前
为什么预览、录制、离线导出不能共享同一个背压策略?
ios·swift
2501_916007474 天前
苹果商店iOS应用上架费用全面解析:开发者计划与审核费用计算
android·ios·小程序·https·uni-app·iphone·webview
2501_916008894 天前
如何实现iOS App代码混淆:SwiftShield使用指南
android·ios·小程序·https·uni-app·iphone·webview
2501_915909064 天前
移动端开发工具链怎么组合比较好,iOS、Android、跨端三套配置方案
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
2501_916008894 天前
怎么用 Godot 导出 iOS 应用并上架 App Store?签名字段该填什么?
android·ios·小程序·https·uni-app·iphone·webview
2501_915918414 天前
iOS编程用什么软件好?主流工具Xcode、AppCode、CodeRunner与新兴快蝎对比
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
终端安全笔记5 天前
iOS 27 之后「策略空转」:设备升级不报错,但旧策略不再管它
android·网络·安全·ios·智能手机
9765033355 天前
iOS 上架 4.3a 被拒【uniapp专讲】
flutter·ios·objective-c·uniapp·swift
黑化旺仔5 天前
【OC】KVO
macos·ios·objective-c·cocoa
HouWan5 天前
SwiftUI 小技巧:如何读取 SwiftUI Font 的详细信息
ios·swiftui·apple