NSURLSession的初步理解

自身是对NSURLConnection的进一步封装,相对于来说使用更简单,而且他自身是一个单例;
他有三个子类:NSURLSessionDownloadTask,NSURLSessionDataTask,NSURLSessionUploadTask;分别对应下载,获取简单数据、上传任务;


注意:当创建的Session做为强引用时,需要自己手动释放

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



Get请求的创建:
方法一:

//1.创建NSURLSession
NSURLSession *session = [NSURLSession sharedSession];
    
//2.根据会话对象来创建task
/*
 第一个参数:请求对象
 第二个参数:completionHandler
 data:响应体
 response:响应头
 error:错误信息
 */
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"链接"]];

NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    //这是使用Json数据解析方式;
    NSLog(@"%@---%@",[NSJSONSerialization JSONObjectWithData: data options:kNilOptions error:nil],[NSThread currentThread]);
    
}];

//3.启动任务
[dataTask resume];

方法二:直接传url

NSURLSession *session = [NSURLSession sharedSession];

NSURL *url = [NSURL URLWithString:@"链接"];

//这里虽然传的是url,但是内部会进行封装成为请求头,默认是get请求;
[[session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
     NSLog(@"%@---%@",[NSJSONSerialization JSONObjectWithData: data options:kNilOptions error:nil],[NSThread currentThread]);
}] resume];


Post请求创建:

NSURLSession *session = [NSURLSession sharedSession];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"链接"]];

request.HTTPMethod = @"POST";
request.HTTPBody = [@"username=5it&pwd=520it&type=JSON" dataUsingEncoding:NSUTF8StringEncoding];

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

[dataTask resume];

NSURLSession代理的使用:
//1.创建session,并设置代理
/*
 第一个参数:配置信息,使用默认;
 第三个参数:控制代理方法在哪个线程调用
 */
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:@"链接"]];
    
[dataTask resume];

//代理方法;
//1.接收到服务器响应的时候调用,在这里需要设置接收数据;
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
    /*
     NSURLSessionResponseCancel
     NSURLSessionResponseAllow = 1,
     NSURLSessionResponseBecomeDownload
     NSURLSessionResponseBecomeStream
     */
    completionHandler(NSURLSessionResponseAllow);
}

//2.接收到服务器返回数据的时候调用,该方法可能会被调用多次
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
}

//3.当请求完成之后调用,如果错误,那么error有值
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
     NSLog(@"didCompleteWithError");
}

使用子类NSURLSessionDownloadTask创建下载任务:

NSURLSession *session = [NSURLSession sharedSession];  
NSURL * url = [NSURL URLWithString:@"h链接"];    
/*
location:文件的临时保存路径
注意:它内部已经完成了边下载边写入数据的操作
*/
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:url completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
   
   //确定文件要存放到哪里
   //caches
   NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
   NSString *fullPath = [caches stringByAppendingPathComponent:response.suggestedFilename];

   //剪切文件到目的地
   NSFileManager *manager = [NSFileManager defaultManager];   
   [manager moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];
}];    
//3.启动
[downloadTask resume];


文件断点下载: 创建的任务都有:挂起、取消、恢复三个操作;
当任务取消时,可以通过方法拿到已经下载的数据:

[self.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
        self.data = resumeData;
}];

当想要继续下载时,可以将已经获取到的数据传人:

self.downloadTask = [self.session downloadTaskWithResumeData:self.data];
[self.downloadTask resume];


然后使用NSURLSessionDownloadTask代理方法:

/*
1.当接收到数据的时候,写数据,该方法会调用多次。bytesWritten:本次写入数据的大小、totalBytesWritten:已经下载完成的数据大小、totalBytesExpectedToWrite:文件大小;
*/
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{

}

//2.恢复下载的时候调用
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
{
}

//3.下载完成之后调用
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
	//改变文件存放的路径;
    NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    NSString *fullPath = [caches stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
    //剪切文件到目的地
    NSFileManager *manager = [NSFileManager defaultManager];
    [manager moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];
}

//4.请求完成之后调用
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
}

使用 NSURLSessionUploadTask创建上传任务:

//1.创建session
self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];

//2.创建task
//PUT
//[session uploadTaskWithRequest:<#(nonnull NSURLRequest *)#> fromFile:<#(nonnull NSURL *)#>]

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/upload"]];
request.HTTPMethod = @"POST";

NSString *header = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary];
[request setValue:header forHTTPHeaderField:@"Content-Type"];
//2.4设置文件上传的文件内容,getBody是获取请求体;请求体拼接的方法和NSURLConnection中的一样;
[[self.session uploadTaskWithRequest:request fromData:[self getBody]] resume];









你可能感兴趣的:(IOS)