iOS开发iOS面试

iOS-大文件下载|断点下载|离线下载

2018-06-26  本文已影响400人  梦蕊dream

一、文件下载-AFN

示例代码

- (void)download{
    AFHTTPSessionManager *manger = [AFHTTPSessionManager manager];
    NSString *url = @"https://ss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=2272971454,2583966854&fm=173&app=25&f=JPEG?w=640&h=621&s=72A22FE3401393E95228E0BA03003047";
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    
    NSURLSessionDownloadTask *loadTask = [manger downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
        //下载进度监听
        NSLog(@"Progress:----%.2f%",100.0*downloadProgress.completedUnitCount/downloadProgress.totalUnitCount);
    } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
        NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];
        NSLog(@"fullPath:%@",fullPath);
        NSLog(@"targetPath:%@",targetPath);
        return [NSURL fileURLWithPath:fullPath];
    } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
        NSLog(@"filePath:%@",filePath);
    }];
    [loadTask resume];
}

二、NSURLConnection

2.1 NSURLConnection下载文件

需要遵行NSURLConnectionDataDelegate
[[NSURLConnection alloc] initWithRequest:request delegate:self]默认是主线程中执行,可以设置代理队列开启子线程。注意不能使用主队列,主队列会使代理方法失效。

开启子线程:
[self.urlConnect setDelegateQueue:[[NSOperationQueue alloc]init]];

子线程里创建 NSURLConnection

如果想子线程里创建 NSURLConnection 并设置代理方法需要如下注意:

1)connectionWithRequest

需要手动开启子线程的 RunLoop,并且不能占用默认 Model


connectionWithRequest

request
The URL request to load. The request object is deep-copied as part of the initialization process. Changes made to request after this method returns do not affect the request that is used for the loading process.
delegate
The delegate object for the connection. The connection calls methods on this delegate as the load progresses. Delegate methods are called on the same thread that called this method. For the connection to work correctly, the calling thread’s run loop must be operating in the default run loop mode

dispatch_async(dispatch_get_global_queue(0, 0), ^{
    NSString *url = @"http://xxx.xxx.com/dist/ab7b54f3-8df0-4678-babc-15a6e4f642b7.mp4";
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
    
    //connectionWithRequest:将NSURLConnection对象作为一个 source 添加到当前 runloop 中,默认运行模式
    self.urlConnect = [NSURLConnection connectionWithRequest:request delegate:self];
    
    [self.urlConnect setDelegateQueue:[[NSOperationQueue alloc]init]];
    [[NSRunLoop currentRunLoop] run];
});
2)initWithRequest
dispatch_async(dispatch_get_global_queue(0, 0), ^{
    NSString *url = @"http://xxx.xxx.com/dist/ab7b54f3-8df0-4678-babc-15a6e4f642b7.mp4";
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
    //断点下载
    NSString *bytes = [NSString stringWithFormat:@"bytes=%zd-",self.currentSize];
    [request setValue:bytes forHTTPHeaderField:@"Range"];
    
    self.urlConnect = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    [self.urlConnect setDelegateQueue:[[NSOperationQueue alloc]init]];
    [[NSRunLoop currentRunLoop] run];
});
  • (void)start;
    Description
    Causes the connection to begin loading data, if it has not already.
    Calling this method is necessary only if you create a connection with the initWithRequest:delegate:startImmediately: method and provide NO for the startImmediately parameter. If you don’t schedule the connection in a run loop or an operation queue before calling this method, the connection is scheduled in the current run loop in the default mode.
dispatch_async(dispatch_get_global_queue(0, 0), ^{
    NSString *url = @"http:// xxx.xxxx.com/dist/ab7b54f3-8df0-4678-babc-15a6e4f642b7.mp4";
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
    //断点下载
    NSString *bytes = [NSString stringWithFormat:@"bytes=%zd-",self.currentSize];
    [request setValue:bytes forHTTPHeaderField:@"Range"];
    
    self.urlConnect = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
    [self.urlConnect setDelegateQueue:[[NSOperationQueue alloc]init]];
    [self.urlConnect start];
});

文件下载示例代码

@property (nonatomic, strong) NSString *fullPath;
@property (nonatomic, assign) NSInteger totalSize;
@property (nonatomic, assign) NSInteger currentSize;
@property (nonatomic, strong) NSFileHandle *fileHandle;

- (void)download{
    NSString *url = @"http://xxx.xxxx.com/dist/ab7b54f3-8df0-4678-babc-15a6e4f642b7.mp4";
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    
    [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
    //文件数据总大小
    self.totalSize = response.expectedContentLength;
    //沙盒路径
    self.fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"123.mp4"];
    //空文件
    [[NSFileManager defaultManager] createFileAtPath:self.fullPath contents:nil attributes:nil];
    //文件句柄
    self.fileHandle = [NSFileHandle fileHandleForWritingAtPath:self.fullPath];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
//
    //1.文件句柄要在文件最后
    [self.fileHandle seekToEndOfFile];
    
    //2.写数据
    [self.fileHandle writeData:data];
    
    self.currentSize += data.length;
    NSLog(@"%.2f%%",100.0*self.currentSize/self.totalSize);
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
    
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
    //关闭文件句柄
    [self.fileHandle closeFile];
    self.fileHandle = nil;
}

2.2 NSURLConnection 断点续传

注意点:

请求头参数:

示例代码:

@property (nonatomic, strong) NSString *fullPath;
@property (nonatomic, assign) NSInteger totalSize;
@property (nonatomic, assign) NSInteger currentSize;
@property (nonatomic, strong) NSFileHandle *fileHandle;
@property (nonatomic, strong) NSURLConnection *urlConnect;

- (IBAction)startDownloadBtn:(UIButton *)sender {
    [self download];
}
- (IBAction)cancelDownloadBtn:(UIButton *)sender {
    [self.urlConnect cancel];
}

修改过代码:

- (void)download{
    NSString *url = @"http://video.yuntoo.com/dist/ab7b54f3-8df0-4678-babc-15a6e4f642b7.mp4";
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
    //断点下载
    NSString *bytes = [NSString stringWithFormat:@"bytes=%zd-",self.currentSize];
    [request setValue:bytes forHTTPHeaderField:@"Range"];
    
    self.urlConnect = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
    
    if (self.currentSize > 0) {
        return;
    }
    //文件请求数据大小,期望大小,并不定是总文件大小
    self.totalSize = response.expectedContentLength;
    //沙盒路径
    self.fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"123.mp4"];
    //空文件
    [[NSFileManager defaultManager] createFileAtPath:self.fullPath contents:nil attributes:nil];
    //文件句柄
    self.fileHandle = [NSFileHandle fileHandleForWritingAtPath:self.fullPath];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
//
    //1.文件句柄要在文件最后
    [self.fileHandle seekToEndOfFile];
    
    //2.写数据
    [self.fileHandle writeData:data];
    
    self.currentSize += data.length;
    NSLog(@"%.2f%%",100.0*self.currentSize/self.totalSize);
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
    NSLog(@"didFailWithError");
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
    //关闭文件句柄
    [self.fileHandle closeFile];
    self.fileHandle = nil;
}

三、NSURLSession

使用步骤

3.1 GET

2种方法都可以。
dataTaskWithURL 内部会自动将请求路径作为参数创建一个请求对象,不可变
回调 Block 是在子线程
dataTaskWithRequest 内部实现边接受数据变写入沙盒操作(tmp)

- (void)sessionDownload{
    NSString *url = @"http://xxx.xxx.com/dist/ab7b54f3-8df0-4678-babc-15a6e4f642b7.mp4";
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    NSURLSession *session = [NSURLSession sharedSession];
    
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSLog(@"completionHandler");
    }];
    
//    NSURLSessionDataTask *dataTask = [[session dataTaskWithURL:[NSURL URLWithString:url]] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//        NSLog(@"completionHandler");
//    }];
    [dataTask resume];
}

3.2 POST

NSString *url = @"http://xxx.xxx.com/login";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
request.HTTPMethod = @"POST";
request.HTTPBody = [@"username=123&pwd=d41d8cd98f00b204e9800998ecf8427e" dataUsingEncoding:NSUTF8StringEncoding];
NSURLSession *session = [NSURLSession sharedSession];

NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    NSLog(@"completionHandler");
}];

//    NSURLSessionDataTask *dataTask = [[session dataTaskWithURL:[NSURL URLWithString:url]] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//        NSLog(@"completionHandler");
//    }];
[dataTask resume];

3.3 代理方法

设置代理

NSString *url = @"http://img1.dongqiudi.com/fastdfs3/M00/1A/CB/ChOxM1swdjmAGg96AAET60fgKms735.jpg";
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
[dataTask resume];

代理方法

//1.接收服务器的响应,默认取消该请求
//completionHandler 回调 传给系统
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{
//    NSURLSessionResponseCancel = 0,取消
//    NSURLSessionResponseAllow = 1,接收
//    NSURLSessionResponseBecomeDownload = 2,下载任务
//    NSURLSessionResponseBecomeStream API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)) = 3,下载任务
    completionHandler(NSURLSessionResponseAllow);
    NSLog(@"%s",__func__);
}
//2.收到返回数据,多次调用
//拼接存储数据
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{
    NSLog(@"%s",__func__);
}
//3.请求结束或失败时调用
//解析数据
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
    NSLog(@"%s",__func__);
}

3.4 文件下载

3.4.1 简单方法-downloadTaskWithRequest

无法监听文件下载进度

- (void)sessionDownloadFile{
    NSString *url = @"http://img1.dongqiudi.com/fastdfs3/M00/1A/CB/ChOxM1swdjmAGg96AAET60fgKms735.jpg";
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    NSURLSession *session = [NSURLSession sharedSession];
    
    NSURLSessionDataTask *dataTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];
        [[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];
        NSLog(@"%@",fullPath);
    }];
    [dataTask resume];
}
3.4.2 代理下载

遵循NSURLSessionDownloadDelegate
使用NSURLSessionDownloadTask

- (void)sessionDownloadFile2{
    NSString *url = @"http://img1.dongqiudi.com/fastdfs3/M00/1A/CB/ChOxM1swdjmAGg96AAET60fgKms735.jpg";
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    NSURLSessionDownloadTask *dataTask = [session downloadTaskWithRequest:request];
    [dataTask resume];
}

代理方法

/**
 * 写数据
 * @param bytesWritten 本次写入数据大小
 * @param totalBytesWritten 下载数据总大小
 * @param totalBytesExpectedToWrite 文件总大小
 */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
    //1.文件下载进度
    NSLog(@"--%.2f%%",100.0*totalBytesWritten/totalBytesExpectedToWrite);
}
/**
 * 恢复下载
 * @param fileOffset 恢复从哪里位置下载
 * @param expectedTotalBytes 文件总大小
 */
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{
    
}
/**
 * 下载完成
 * @param location 文件临时存储路径
 */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
    NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
    [[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];
    NSLog(@"%@",fullPath);
}

/**
 * 请求结束
 */
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
    NSLog(@"didCompleteWithError");
}

3.5 大文件断点下载-NSURLSessionDownloadTask

注意点:

@property (nonatomic, strong) NSURLSessionDownloadTask *downloadTask;
@property (nonatomic, strong) NSData *resumeData;
@property (nonatomic, strong) NSURLSession *session;

点击方法

//开始下载
- (IBAction)startDownloadBtn:(UIButton *)sender {
    [self sessionDownloadFile2];
//    [self download];
}
//取消下载
- (IBAction)cancelDownloadBtn:(UIButton *)sender {
    NSLog(@"-----------------cancelDownloadBtn");
//    [self.downloadTask cancel];
    //cancel:不可恢复的
    //cancelByProducingResumeData:可恢复的
    //恢复下载数据!= 文件数据
    [self.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
        self.resumeData = resumeData;
    }];
}
//暂停下载
- (IBAction)suspendBtn:(UIButton *)sender {
    NSLog(@"-----------------suspendBtn");
    [self.downloadTask suspend];
}
//继续下载
- (IBAction)goONBtn:(UIButton *)sender {
    NSLog(@"-----------------goONBtn");
//    NSURLSessionTaskStateRunning = 0,
//    NSURLSessionTaskStateSuspended = 1,
//    NSURLSessionTaskStateCanceling = 2,
//    NSURLSessionTaskStateCompleted = 3,
    if (self.downloadTask.state == NSURLSessionTaskStateCompleted) {
        if (self.resumeData) {
            //resumeData 有值表示取消下载
            self.downloadTask = [self.session downloadTaskWithResumeData:self.resumeData];
        }
    }
    [self.downloadTask resume];
}

NSURLSessionDownloadTask初始化和代理方法


- (void)sessionDownloadFile2{
    NSString *url = @"http://video.yuntoo.com/dist/ab7b54f3-8df0-4678-babc-15a6e4f642b7.mp4";
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    NSURLSessionDownloadTask *downloadTask = [self.session downloadTaskWithRequest:request];
    [downloadTask resume];
    self.downloadTask = downloadTask;
}

/**
 * 写数据
 * @param bytesWritten 本次写入数据大小
 * @param totalBytesWritten 下载数据总大小
 * @param totalBytesExpectedToWrite 文件总大小
 */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
    //1.文件下载进度
    NSLog(@"%.2f%%",100.0 *totalBytesWritten/totalBytesExpectedToWrite);
}
/**
 * 恢复下载
 * @param fileOffset 恢复从哪里位置下载
 * @param expectedTotalBytes 文件总大小
 */
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{
    
}
/**
 * 下载完成
 * @param location 文件临时存储路径
 */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
    NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
    [[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];
    NSLog(@"%@",fullPath);
}

/**
 * 请求结束
 */
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
    NSLog(@"didCompleteWithError");
}

3.6 大文件离线断点下载-NSURLSessionDataTask

遵循NSURLSessionDataDelegate
使用NSURLSessionDataTask

全局变量

@property (nonatomic, strong) NSString *fullPath;
@property (nonatomic, assign) NSInteger totalSize;
@property (nonatomic, assign) NSInteger currentSize;
@property (nonatomic, strong) NSFileHandle *fileHandle;
@property (nonatomic, strong) NSURLSessionDataTask *dataTask;
-(NSString *)fullPath{
    if (_fullPath == nil) {
        _fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"1234.mp4"];
    }
    return _fullPath;
}

初始化NSURLSessionDataTask

-(NSURLSessionDataTask *)dataTask{
    if (_dataTask == nil) {
        NSString *url = @"http://xxx.xxxx.com/dist/ab7b54f3-8df0-4678-babc-15a6e4f642b7.mp4";
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
        NSDictionary *fileDict = [[NSFileManager defaultManager] attributesOfItemAtPath:self.fullPath error:nil];
        self.currentSize = [[fileDict valueForKey:@"NSFileSize"] integerValue];
        NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.currentSize];
        [request setValue:range forHTTPHeaderField:@"Range"];
        NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
        _dataTask = [session dataTaskWithRequest:request];
    }
    return _dataTask;
}

开始、取消、继续、暂停方法

//开始下载
- (IBAction)startDownloadBtn:(UIButton *)sender {
    NSLog(@"-----------------startDownloadBtn");
    [self.dataTask resume];
}
//取消下载
- (IBAction)cancelDownloadBtn:(UIButton *)sender {
    NSLog(@"-----------------cancelDownloadBtn");
    [self.dataTask cancel];
    self.dataTask = nil;
}
//暂停下载
- (IBAction)suspendBtn:(UIButton *)sender {
    NSLog(@"-----------------suspendBtn");
    [self.dataTask suspend];
}
//继续下载
- (IBAction)goONBtn:(UIButton *)sender {
    NSLog(@"-----------------goONBtn");
    [self.dataTask resume];
}

代理方法

//1.接收服务器的响应,默认取消该请求
//completionHandler 回调 传给系统
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{
//    NSURLSessionResponseCancel = 0,取消
//    NSURLSessionResponseAllow = 1,接收
//    NSURLSessionResponseBecomeDownload = 2,下载任务
//    NSURLSessionResponseBecomeStream API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0),
    if (self.currentSize == 0) {
        [[NSFileManager defaultManager] createFileAtPath:self.fullPath contents:nil attributes:nil];
    }
    
    self.fileHandle = [NSFileHandle fileHandleForWritingAtPath:_fullPath];
    self.totalSize = response.expectedContentLength+self.currentSize;
    completionHandler(NSURLSessionResponseAllow);
}
//2.收到返回数据,多次调用
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{
    [self.fileHandle seekToEndOfFile];
    [self.fileHandle writeData:data];
    self.currentSize += data.length;
    NSLog(@"%.2f",100.0* self.currentSize / self.totalSize);
}
//3.请求结束或失败时调用
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
    [self.fileHandle closeFile];
    self.fileHandle = nil;
    NSLog(@"didCompleteWithError:%@",_fullPath);
}

Session 释放

-(void)dealloc{
    [self.session invalidateAndCancel];
}


其他

输出流

保存数据
初始化

//输出流指向地址没有文件会新建文件
    self.outStream = [[NSOutputStream alloc] initToFileAtPath:self.fullPath append:YES];
    [self.outStream open];

写数据

[self.outStream write:data.bytes maxLength:data.length];

关闭

 [self.outStream close];
上一篇下一篇

猜你喜欢

热点阅读