NSURLSession
使用步驟
使用NSURLSession對象創(chuàng)建Task,然后執(zhí)行Task
-(void)get
{
//1.確定URL
NSURL*url = [NSURLURLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];
//2.創(chuàng)建請求對象
NSURLRequest*request =[NSURLRequestrequestWithURL:url];
//3.創(chuàng)建會話對象
NSURLSession*session = [NSURLSessionsharedSession];
//4.創(chuàng)建Task
/*
第一個參數(shù):請求對象
第二個參數(shù):completionHandler當(dāng)請求完成之后調(diào)用
data:響應(yīng)體信息
response:響應(yīng)頭信息
error:錯誤信息當(dāng)請求失敗的時候error有值
*/
NSURLSessionDataTask*dataTask = [sessiondataTaskWithRequest:requestcompletionHandler:^(NSData*_Nullabledata,NSURLResponse*_Nullableresponse,NSError*_Nullableerror) {
//6.解析數(shù)據(jù)
NSLog(@"%@",[[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding]);
}];
//5.執(zhí)行Task
[dataTaskresume];
}
-(void)get2
{
//1.確定URL
NSURL*url = [NSURLURLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];
//2.創(chuàng)建請求對象
//NSURLRequest *request =[NSURLRequest requestWithURL:url];
//3.創(chuàng)建會話對象
NSURLSession*session = [NSURLSessionsharedSession];
//4.創(chuàng)建Task
/*
第一個參數(shù):請求路徑
第二個參數(shù):completionHandler當(dāng)請求完成之后調(diào)用
data:響應(yīng)體信息
response:響應(yīng)頭信息
error:錯誤信息當(dāng)請求失敗的時候error有值
注意:dataTaskWithURL內(nèi)部會自動的將請求路徑作為參數(shù)創(chuàng)建一個請求對象(GET)
*/
NSURLSessionDataTask*dataTask = [sessiondataTaskWithURL:urlcompletionHandler:^(NSData*_Nullabledata,NSURLResponse*_Nullableresponse,NSError*_Nullableerror) {
//6.解析數(shù)據(jù)
NSLog(@"%@",[[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding]);
}];
//5.執(zhí)行Task
[dataTaskresume];
}
-(void)post
{
//1.確定URL
NSURL*url = [NSURLURLWithString:@"http://120.25.226.186:32812/login"];
//2.創(chuàng)建請求對象
NSMutableURLRequest*request =[NSMutableURLRequestrequestWithURL:url];
//2.1設(shè)置請求方法為post
request.HTTPMethod=@"POST";
//2.2設(shè)置請求體
request.HTTPBody= [@"username=520it&pwd=520it&type=JSON"dataUsingEncoding:NSUTF8StringEncoding];
//3.創(chuàng)建會話對象
NSURLSession*session = [NSURLSessionsharedSession];
//4.創(chuàng)建Task
/*
第一個參數(shù):請求對象
第二個參數(shù):completionHandler當(dāng)請求完成之后調(diào)用!!!在子線程中調(diào)用
data:響應(yīng)體信息
response:響應(yīng)頭信息
error:錯誤信息當(dāng)請求失敗的時候error有值
*/
NSURLSessionDataTask*dataTask = [sessiondataTaskWithRequest:requestcompletionHandler:^(NSData*_Nullabledata,NSURLResponse*_Nullableresponse,NSError*_Nullableerror) {
NSLog(@"%@",[NSThreadcurrentThread]);
//6.解析數(shù)據(jù)
NSLog(@"%@",[[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding]);
}];
//5.執(zhí)行Task
[dataTaskresume];
}
NSURLSession代理方法
#import"ViewController.h"
@interfaceViewController()
/**接受響應(yīng)體信息*/
@property(nonatomic,strong)NSMutableData*fileData;
@end
@implementationViewController
-(NSMutableData*)fileData
{
if(_fileData==nil) {
_fileData= [NSMutableDatadata];
}
return_fileData;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event
{
//1.url
NSURL*url = [NSURLURLWithString:@"http://120.25.226.186:32812/login?username=123&pwd=123&type=JSON"];
//2.創(chuàng)建請求對象
NSURLRequest*request = [NSURLRequestrequestWithURL:url];
//3.創(chuàng)建會話對象,設(shè)置代理
/*
第一個參數(shù):配置信息[NSURLSessionConfiguration defaultSessionConfiguration]
第二個參數(shù):代理
第三個參數(shù):設(shè)置代理方法在哪個線程中調(diào)用
*/
NSURLSession*session = [NSURLSessionsessionWithConfiguration:[NSURLSessionConfigurationdefaultSessionConfiguration]delegate:selfdelegateQueue:[NSOperationQueuemainQueue]];
//4.創(chuàng)建Task
NSURLSessionDataTask*dataTask = [sessiondataTaskWithRequest:request];
//5.執(zhí)行Task
[dataTaskresume];
}
#pragma mark ----------------------
#pragma mark NSURLSessionDataDelegate
/**
*1.接收到服務(wù)器的響應(yīng)它默認(rèn)會取消該請求
*
*@param session會話對象
*@param dataTask請求任務(wù)
*@param response響應(yīng)頭信息
*@param completionHandler回調(diào)傳給系統(tǒng)
*/
-(void)URLSession:(NSURLSession*)session dataTask:(NSURLSessionDataTask*)dataTask didReceiveResponse:(NSURLResponse*)response completionHandler:(void(^)(NSURLSessionResponseDisposition))completionHandler
{
NSLog(@"%s",__func__);
/*
NSURLSessionResponseCancel = 0,取消默認(rèn)
NSURLSessionResponseAllow = 1,接收
NSURLSessionResponseBecomeDownload = 2,變成下載任務(wù)
NSURLSessionResponseBecomeStream變成流
*/
completionHandler(NSURLSessionResponseAllow);
}
/**
*接收到服務(wù)器返回的數(shù)據(jù)調(diào)用多次
*
*@param session會話對象
*@param dataTask請求任務(wù)
*@param data本次下載的數(shù)據(jù)
*/
-(void)URLSession:(NSURLSession*)session dataTask:(NSURLSessionDataTask*)dataTask didReceiveData:(NSData*)data
{
NSLog(@"%s",__func__);
//拼接數(shù)據(jù)
[self.fileDataappendData:data];
}
/**
*請求結(jié)束或者是失敗的時候調(diào)用
*
*@param session會話對象
*@param dataTask請求任務(wù)
*@param error錯誤信息
*/
-(void)URLSession:(NSURLSession*)session task:(NSURLSessionTask*)task didCompleteWithError:(NSError*)error
{
NSLog(@"%s",__func__);
//解析數(shù)據(jù)
NSLog(@"%@",[[NSStringalloc]initWithData:self.fileDataencoding:NSUTF8StringEncoding]);
}
@end
NSURLSessionDownloadTask大文件下載(block)
//優(yōu)點:不需要擔(dān)心內(nèi)存
//缺點:無法監(jiān)聽文件下載進度
-(void)download
{
//1.url
NSURL*url = [NSURLURLWithString:@"http://120.25.226.186:32812/resources/images/minion_03.png"];
//2.創(chuàng)建請求對象
NSURLRequest*request = [NSURLRequestrequestWithURL:url];
//3.創(chuàng)建session
NSURLSession*session = [NSURLSessionsharedSession];
//4.創(chuàng)建Task
/*
第一個參數(shù):請求對象
第二個參數(shù):completionHandler回調(diào)
location:
response:響應(yīng)頭信息
error:錯誤信息
*/
//該方法內(nèi)部已經(jīng)實現(xiàn)了邊接受數(shù)據(jù)邊寫沙盒(tmp)的操作
NSURLSessionDownloadTask*downloadTask = [sessiondownloadTaskWithRequest:requestcompletionHandler:^(NSURL*_Nullablelocation,NSURLResponse*_Nullableresponse,NSError*_Nullableerror) {
//6.處理數(shù)據(jù)
NSLog(@"%@---%@",location,[NSThreadcurrentThread]);
//6.1拼接文件全路徑
NSString*fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES)lastObject]stringByAppendingPathComponent:response.suggestedFilename];
//6.2剪切文件
[[NSFileManagerdefaultManager]moveItemAtURL:locationtoURL:[NSURLfileURLWithPath:fullPath]error:nil];
NSLog(@"%@",fullPath);
}];
//5.執(zhí)行Task
[downloadTaskresume];
}
@end
-(void)delegate
{
//1.url
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_03.png"];
//2.創(chuàng)建請求對象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.創(chuàng)建session
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
//4.創(chuàng)建Task
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request];
//5.執(zhí)行Task
[downloadTask resume];
}
#pragma mark ----------------------
#pragma mark NSURLSessionDownloadDelegate
/**
*? 寫數(shù)據(jù)
*
*? @param session? ? ? ? ? ? ? ? ? 會話對象
*? @param downloadTask? ? ? ? ? ? ? 下載任務(wù)
*? @param bytesWritten? ? ? ? ? ? ? 本次寫入的數(shù)據(jù)大小
*? @param totalBytesWritten? ? ? ? 下載的數(shù)據(jù)總大小
*? @param totalBytesExpectedToWrite? 文件的總大小
*/
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
//1. 獲得文件的下載進度
NSLog(@"%f",1.0 * totalBytesWritten/totalBytesExpectedToWrite);
}
/**
*? 當(dāng)恢復(fù)下載的時候調(diào)用該方法
*
*? @param fileOffset? ? ? ? 從什么地方下載
*? @param expectedTotalBytes 文件的總大小
*/
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
{
NSLog(@"%s",__func__);
}
/**
*? 當(dāng)下載完成的時候調(diào)用
*
*? @param location? ? 文件的臨時存儲路徑
*/
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
NSLog(@"%@",location);
//1 拼接文件全路徑
NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
//2 剪切文件
[[NSFileManager defaultManager]moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];
NSLog(@"%@",fullPath);
}
/**
*? 請求結(jié)束
*/
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
NSLog(@"didCompleteWithError");
}
@end
NSURLSessionDownloadTask大文件下載(斷點下載)
@interface ViewController ()@property (nonatomic, strong) NSURLSessionDownloadTask *downloadTask;
@property (nonatomic, strong) NSData *resumData;
@property (nonatomic, strong) NSURLSession *session;
@end
@implementation ViewController
- (IBAction)startBtnClick:(id)sender
{
//1.url
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];
//2.創(chuàng)建請求對象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.創(chuàng)建session
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
self.session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
//4.創(chuàng)建Task
NSURLSessionDownloadTask *downloadTask = [self.session downloadTaskWithRequest:request];
//5.執(zhí)行Task
[downloadTask resume];
self.downloadTask = downloadTask;
}
//暫停是可以恢復(fù)
- (IBAction)suspendBtnClick:(id)sender
{
NSLog(@"+++++++++++++++++++暫停");
[self.downloadTask suspend];
}
//cancel:取消是不能恢復(fù)
//cancelByProducingResumeData:是可以恢復(fù)
- (IBAction)cancelBtnClick:(id)sender
{
NSLog(@"+++++++++++++++++++取消");
//[self.downloadTask cancel];
//恢復(fù)下載的數(shù)據(jù)!=文件數(shù)據(jù)
[self.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
self.resumData = resumeData;
}];
}
- (IBAction)goOnBtnClick:(id)sender
{
NSLog(@"+++++++++++++++++++恢復(fù)下載");
if(self.resumData)
{
self.downloadTask = [self.session downloadTaskWithResumeData:self.resumData];
}
[self.downloadTask resume];
}
//優(yōu)點:不需要擔(dān)心內(nèi)存
//缺點:無法監(jiān)聽文件下載進度
-(void)download
{
//1.url
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_03.png"];
//2.創(chuàng)建請求對象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.創(chuàng)建session
NSURLSession *session = [NSURLSession sharedSession];
//4.創(chuàng)建Task
/*
第一個參數(shù):請求對象
第二個參數(shù):completionHandler 回調(diào)
location:
response:響應(yīng)頭信息
error:錯誤信息
*/
//該方法內(nèi)部已經(jīng)實現(xiàn)了邊接受數(shù)據(jù)邊寫沙盒(tmp)的操作
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//6.處理數(shù)據(jù)
NSLog(@"%@---%@",location,[NSThread currentThread]);
//6.1 拼接文件全路徑
NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];
//6.2 剪切文件
[[NSFileManager defaultManager]moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];
NSLog(@"%@",fullPath);
}];
//5.執(zhí)行Task
[downloadTask resume];
}
#pragma mark ----------------------
#pragma mark NSURLSessionDownloadDelegate
/**
*? 寫數(shù)據(jù)
*
*? @param session? ? ? ? ? ? ? ? ? 會話對象
*? @param downloadTask? ? ? ? ? ? ? 下載任務(wù)
*? @param bytesWritten? ? ? ? ? ? ? 本次寫入的數(shù)據(jù)大小
*? @param totalBytesWritten? ? ? ? 下載的數(shù)據(jù)總大小
*? @param totalBytesExpectedToWrite? 文件的總大小
*/
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
//1. 獲得文件的下載進度
NSLog(@"%f",1.0 * totalBytesWritten/totalBytesExpectedToWrite);
}
/**
*? 當(dāng)恢復(fù)下載的時候調(diào)用該方法
*
*? @param fileOffset? ? ? ? 從什么地方下載
*? @param expectedTotalBytes 文件的總大小
*/
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
{
NSLog(@"%s",__func__);
}
/**
*? 當(dāng)下載完成的時候調(diào)用
*
*? @param location? ? 文件的臨時存儲路徑
*/
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
NSLog(@"%@",location);
//1 拼接文件全路徑
NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
//2 剪切文件
[[NSFileManager defaultManager]moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];
NSLog(@"%@",fullPath);
}
/**
*? 請求結(jié)束
*/
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
NSLog(@"didCompleteWithError");
}
@end
使用NSURLSessionDataTask實現(xiàn)大文件下載
#import "ViewController.h"@interface ViewController ()@property (weak, nonatomic) IBOutlet UIProgressView *proessView;/** 接受響應(yīng)體信息 */@property (nonatomic, strong) NSFileHandle *handle;@property (nonatomic, assign) NSInteger totalSize;@property (nonatomic, assign) NSInteger currentSize;@property (nonatomic, strong) NSString *fullPath;@end@implementation ViewController-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event
{
//1.url
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_02.mp4"];
//2.創(chuàng)建請求對象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.創(chuàng)建會話對象,設(shè)置代理
/*
第一個參數(shù):配置信息 [NSURLSessionConfiguration defaultSessionConfiguration]
第二個參數(shù):代理
第三個參數(shù):設(shè)置代理方法在哪個線程中調(diào)用
*/
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
//4.創(chuàng)建Task
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
//5.執(zhí)行Task
[dataTask resume];
}
#pragma mark ----------------------
#pragma mark NSURLSessionDataDelegate
/**
*? 1.接收到服務(wù)器的響應(yīng) 它默認(rèn)會取消該請求
*
*? @param session? ? ? ? ? 會話對象
*? @param dataTask? ? ? ? ? 請求任務(wù)
*? @param response? ? ? ? ? 響應(yīng)頭信息
*? @param completionHandler 回調(diào) 傳給系統(tǒng)
*/
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
//獲得文件的總大小
self.totalSize = response.expectedContentLength;
//獲得文件全路徑
self.fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];
//創(chuàng)建空的文件
[[NSFileManager defaultManager]createFileAtPath:self.fullPath contents:nil attributes:nil];
//創(chuàng)建文件句柄
self.handle = [NSFileHandle fileHandleForWritingAtPath:self.fullPath];
[self.handle seekToEndOfFile];
/*
NSURLSessionResponseCancel = 0,取消 默認(rèn)
NSURLSessionResponseAllow = 1, 接收
NSURLSessionResponseBecomeDownload = 2, 變成下載任務(wù)
NSURLSessionResponseBecomeStream? ? ? ? 變成流
*/
completionHandler(NSURLSessionResponseAllow);
}
/**
*? 接收到服務(wù)器返回的數(shù)據(jù) 調(diào)用多次
*
*? @param session? ? ? ? ? 會話對象
*? @param dataTask? ? ? ? ? 請求任務(wù)
*? @param data? ? ? ? ? ? ? 本次下載的數(shù)據(jù)
*/
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
//寫入數(shù)據(jù)到文件
[self.handle writeData:data];
//計算文件的下載進度
self.currentSize += data.length;
NSLog(@"%f",1.0 * self.currentSize / self.totalSize);
self.proessView.progress = 1.0 * self.currentSize / self.totalSize;
}
/**
*? 請求結(jié)束或者是失敗的時候調(diào)用
*
*? @param session? ? ? ? ? 會話對象
*? @param dataTask? ? ? ? ? 請求任務(wù)
*? @param error? ? ? ? ? ? 錯誤信息
*/
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
NSLog(@"%@",self.fullPath);
//關(guān)閉文件句柄
[self.handle closeFile];
self.handle = nil;
}
@end
NSURLSessionDataTask離線斷點下載(斷點續(xù)傳)
-(void)viewDidLoad
{
[super viewDidLoad];
//1.讀取保存的文件總大小的數(shù)據(jù),0
//2.獲得當(dāng)前已經(jīng)下載的數(shù)據(jù)的大小
//3.計算得到進度信息
}
-(NSString *)fullPath
{
if (_fullPath == nil) {
//獲得文件全路徑
_fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:FileName];
}
return _fullPath;
}
-(NSURLSession *)session
{
if (_session == nil) {
//3.創(chuàng)建會話對象,設(shè)置代理
/*
第一個參數(shù):配置信息 [NSURLSessionConfiguration defaultSessionConfiguration]
第二個參數(shù):代理
第三個參數(shù):設(shè)置代理方法在哪個線程中調(diào)用
*/
_session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
}
return _session;
}
-(NSURLSessionDataTask *)dataTask
{
if (_dataTask == nil) {
//1.url
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];
//2.創(chuàng)建請求對象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//3 設(shè)置請求頭信息,告訴服務(wù)器請求那一部分?jǐn)?shù)據(jù)
self.currentSize = [self getFileSize];
NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.currentSize];
[request setValue:range forHTTPHeaderField:@"Range"];
//4.創(chuàng)建Task
_dataTask = [self.session dataTaskWithRequest:request];
}
return _dataTask;
}
-(NSInteger)getFileSize
{
//獲得指定文件路徑對應(yīng)文件的數(shù)據(jù)大小
NSDictionary *fileInfoDict = [[NSFileManager defaultManager]attributesOfItemAtPath:self.fullPath error:nil];
NSLog(@"%@",fileInfoDict);
NSInteger currentSize = [fileInfoDict[@"NSFileSize"] integerValue];
return currentSize;
}
- (IBAction)startBtnClick:(id)sender
{
[self.dataTask resume];
}
- (IBAction)suspendBtnClick:(id)sender
{
NSLog(@"_________________________suspend");
[self.dataTask suspend];
}
//注意:dataTask的取消是不可以恢復(fù)的
- (IBAction)cancelBtnClick:(id)sender
{
NSLog(@"_________________________cancel");
[self.dataTask cancel];
self.dataTask = nil;
}
- (IBAction)goOnBtnClick:(id)sender
{
NSLog(@"_________________________resume");
[self.dataTask resume];
}
#pragma mark ----------------------
#pragma mark NSURLSessionDataDelegate
/**
*? 1.接收到服務(wù)器的響應(yīng) 它默認(rèn)會取消該請求
*
*? @param session? ? ? ? ? 會話對象
*? @param dataTask? ? ? ? ? 請求任務(wù)
*? @param response? ? ? ? ? 響應(yīng)頭信息
*? @param completionHandler 回調(diào) 傳給系統(tǒng)
*/
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
//獲得文件的總大小
//expectedContentLength 本次請求的數(shù)據(jù)大小
self.totalSize = response.expectedContentLength + self.currentSize;
if (self.currentSize == 0) {
//創(chuàng)建空的文件
[[NSFileManager defaultManager]createFileAtPath:self.fullPath contents:nil attributes:nil];
}
//創(chuàng)建文件句柄
self.handle = [NSFileHandle fileHandleForWritingAtPath:self.fullPath];
//移動指針
[self.handle seekToEndOfFile];
/*
NSURLSessionResponseCancel = 0,取消 默認(rèn)
NSURLSessionResponseAllow = 1, 接收
NSURLSessionResponseBecomeDownload = 2, 變成下載任務(wù)
NSURLSessionResponseBecomeStream? ? ? ? 變成流
*/
completionHandler(NSURLSessionResponseAllow);
}
/**
*? 接收到服務(wù)器返回的數(shù)據(jù) 調(diào)用多次
*
*? @param session? ? ? ? ? 會話對象
*? @param dataTask? ? ? ? ? 請求任務(wù)
*? @param data? ? ? ? ? ? ? 本次下載的數(shù)據(jù)
*/
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
//寫入數(shù)據(jù)到文件
[self.handle writeData:data];
//計算文件的下載進度
self.currentSize += data.length;
NSLog(@"%f",1.0 * self.currentSize / self.totalSize);
self.proessView.progress = 1.0 * self.currentSize / self.totalSize;
}
/**
*? 請求結(jié)束或者是失敗的時候調(diào)用
*
*? @param session? ? ? ? ? 會話對象
*? @param dataTask? ? ? ? ? 請求任務(wù)
*? @param error? ? ? ? ? ? 錯誤信息
*/
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
NSLog(@"%@",self.fullPath);
//關(guān)閉文件句柄
[self.handle closeFile];
self.handle = nil;
}
-(void)dealloc
{
//清理工作
//finishTasksAndInvalidate
[self.session invalidateAndCancel];
}
@end
(1)關(guān)于NSOutputStream的使用
//1. 創(chuàng)建一個輸入流,數(shù)據(jù)追加到文件的屁股上
//把數(shù)據(jù)寫入到指定的文件地址,如果當(dāng)前文件不存在,則會自動創(chuàng)建
NSOutputStream *stream = [[NSOutputStream alloc]initWithURL:[NSURL fileURLWithPath:[self fullPath]] append:YES];
//2. 打開流
[stream open];
//3. 寫入流數(shù)據(jù)
[stream write:data.bytes maxLength:data.length];
//4.當(dāng)不需要的時候應(yīng)該關(guān)閉流
[stream close];
(2)關(guān)于網(wǎng)絡(luò)請求請求頭的設(shè)置(可以設(shè)置請求下載文件的某一部分)
//1. 設(shè)置請求對象
//1.1 創(chuàng)建請求路徑
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];
//1.2 創(chuàng)建可變請求對象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//1.3 拿到當(dāng)前文件的殘留數(shù)據(jù)大小
self.currentContentLength = [self FileSize];
//1.4 告訴服務(wù)器從哪個地方開始下載文件數(shù)據(jù)
NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.currentContentLength];
NSLog(@"%@",range);
//1.5 設(shè)置請求頭
[request setValue:range forHTTPHeaderField:@"Range"];
(3)NSURLSession對象的釋放
-(void)dealloc
{
//在最后的時候應(yīng)該把session釋放,以免造成內(nèi)存泄露
//? ? NSURLSession設(shè)置過代理后,需要在最后(比如控制器銷毀的時候)調(diào)用session的invalidateAndCancel或者resetWithCompletionHandler,才不會有內(nèi)存泄露
//? ? [self.session invalidateAndCancel];
[self.session resetWithCompletionHandler:^{
NSLog(@"釋放---");
}];
}
(4)優(yōu)化部分
01 關(guān)于文件下載進度的實時更新
02 方法的獨立與抽取
NSURLSession實現(xiàn)文件上傳
(1)實現(xiàn)文件上傳的方法
/*
第一個參數(shù):請求對象
第二個參數(shù):請求體(要上傳的文件數(shù)據(jù))
block回調(diào):
NSData:響應(yīng)體
NSURLResponse:響應(yīng)頭
NSError:請求的錯誤信息
*/
NSURLSessionUploadTask *uploadTask =? [session uploadTaskWithRequest:request fromData:data completionHandler:^(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error)
(2)設(shè)置代理,在代理方法中監(jiān)聽文件上傳進度
/*
調(diào)用該方法上傳文件數(shù)據(jù)
如果文件數(shù)據(jù)很大,那么該方法會被調(diào)用多次
參數(shù)說明:
totalBytesSent:已經(jīng)上傳的文件數(shù)據(jù)的大小
totalBytesExpectedToSend:文件的總大小
*/
-(void)URLSession:(nonnull NSURLSession *)session task:(nonnull NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
{
NSLog(@"%.2f",1.0 * totalBytesSent/totalBytesExpectedToSend);
}
(3)關(guān)于NSURLSessionConfiguration相關(guān)
01 作用:可以統(tǒng)一配置NSURLSession,如請求超時等
02 創(chuàng)建的方式和使用
//創(chuàng)建配置的三種方式
+ (NSURLSessionConfiguration *)defaultSessionConfiguration;
+ (NSURLSessionConfiguration *)ephemeralSessionConfiguration;
+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier NS_AVAILABLE(10_10, 8_0);
//統(tǒng)一配置NSURLSession
-(NSURLSession *)session
{
if (_session == nil) {
//創(chuàng)建NSURLSessionConfiguration
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
//設(shè)置請求超時為10秒鐘
config.timeoutIntervalForRequest = 10;
//在蜂窩網(wǎng)絡(luò)情況下是否繼續(xù)請求(上傳或下載)
config.allowsCellularAccess = NO;
_session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
}
return _session;
}
#import "ViewController.h"http://? ? ? ? ? ? ? ? ? ----WebKitFormBoundaryvMI3CAV0sGUtL8tr#define Kboundary @"----WebKitFormBoundaryjv0UfA04ED44AhWx"#define KNewLine [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]@interface ViewController ()/** 注釋 */@property (nonatomic, strong) NSURLSession *session;@end
@implementation ViewController
-(NSURLSession *)session
{? ??
if (_session == nil) {? ? ? ?
?NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];? ? ? ? ? ? ? ? //是否運行蜂窩訪問? ? ? ??
config.allowsCellularAccess = YES;? ? ? ?
?config.timeoutIntervalForRequest = 15;? ? ? ? ? ? ? ??
_session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];??
? }? ??
return _session;
}-
(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event
{
[self upload2];
}
-(void)upload
{
//1.url
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"];
//2.創(chuàng)建請求對象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//2.1 設(shè)置請求方法
request.HTTPMethod = @"POST";
//2.2 設(shè)請求頭信息
[request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary] forHTTPHeaderField:@"Content-Type"];
//3.創(chuàng)建會話對象
//? ? NSURLSession *session = [NSURLSession sharedSession];
//4.創(chuàng)建上傳TASK
/*
第一個參數(shù):請求對象
第二個參數(shù):傳遞是要上傳的數(shù)據(jù)(請求體)
第三個參數(shù):
*/
NSURLSessionUploadTask *uploadTask = [self.session uploadTaskWithRequest:request fromData:[self getBodyData] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//6.解析
NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
}];
//5.執(zhí)行Task
[uploadTask resume];
}
-(void)upload2
{
//1.url
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"];
//2.創(chuàng)建請求對象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//2.1 設(shè)置請求方法
request.HTTPMethod = @"POST";
//2.2 設(shè)請求頭信息
[request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary] forHTTPHeaderField:@"Content-Type"];
//3.創(chuàng)建會話對象
//4.創(chuàng)建上傳TASK
/*
第一個參數(shù):請求對象
第二個參數(shù):傳遞是要上傳的數(shù)據(jù)(請求體)
*/
NSURLSessionUploadTask *uploadTask = [self.session uploadTaskWithRequest:request fromData:[self getBodyData] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//6.解析
NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
}];
//5.執(zhí)行Task
[uploadTask resume];
}
-(NSData *)getBodyData
{
NSMutableData *fileData = [NSMutableData data];
//5.1 文件參數(shù)
/*
--分隔符
Content-Disposition: form-data; name="file"; filename="Snip20160225_341.png"
Content-Type: image/png(MIMEType:大類型/小類型)
空行
文件參數(shù)
*/
[fileData appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
//name:file 服務(wù)器規(guī)定的參數(shù)
//filename:Snip20160225_341.png 文件保存到服務(wù)器上面的名稱
//Content-Type:文件的類型
[fileData appendData:[@"Content-Disposition: form-data; name=\"file\"; filename=\"Sss.png\"" dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
[fileData appendData:[@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
[fileData appendData:KNewLine];
UIImage *image = [UIImage imageNamed:@"Snip20160226_90"];
//UIImage --->NSData
NSData *imageData = UIImagePNGRepresentation(image);
[fileData appendData:imageData];
[fileData appendData:KNewLine];
//5.2 非文件參數(shù)
/*
--分隔符
Content-Disposition: form-data; name="username"
空行
123456
*/
[fileData appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
[fileData appendData:[@"Content-Disposition: form-data; name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
[fileData appendData:KNewLine];
[fileData appendData:[@"123456" dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
//5.3 結(jié)尾標(biāo)識
/*
--分隔符--
*/
[fileData appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
return fileData;
}
#pragma mark ----------------------
#pragma mark NSURLSessionDataDelegate
/*
*? @param bytesSent? ? ? ? ? ? ? ? 本次發(fā)送的數(shù)據(jù)
*? @param totalBytesSent? ? ? ? ? 上傳完成的數(shù)據(jù)大小
*? @param totalBytesExpectedToSend 文件的總大小
*/
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
{
NSLog(@"%f",1.0 *totalBytesSent / totalBytesExpectedToSend);
}
@end