iOS網(wǎng)絡(luò)編程(十)

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容