iOS开发攻城狮的集散地iOS底层基础知识iOS面试知识点

iOS-NSURLSession与NSURLConnection

2019-04-02  本文已影响8人  路飞_Luck
一 使用现状

NSURLSession是NSURLConnection 的替代者,在2013年苹果全球开发者大会(WWDC2013)随ios7一起发布,是对NSURLConnection进行了重构优化后的新的网络访问接口。从iOS9.0开始, NSURLConnection中发送请求的两个方法已过期(同步请求,异步请求),初始化网络连接(initWithRequest: delegate:)的方法也被设置为过期,系统不再推荐使用,建议使用NSURLSession发送网络请求。

// macos(10.3,10.11), ios(2.0,9.0), tvos(9.0,9.0)
+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request
                 returningResponse:(NSURLResponse **)response
                             error:(NSError **)error;
//  macos(10.7,10.11), ios(5.0,9.0), tvos(9.0,9.0)
+ (void)sendAsynchronousRequest:(NSURLRequest*) request
                          queue:(NSOperationQueue*) queue
              completionHandler:(void (^)(NSURLResponse*response, NSData*data, NSError* connectionError));
// macos(10.5,10.11), ios(2.0,9.0), tvos(9.0,9.0)
- (instancetype)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately;

// macos(10.3,10.11), ios(2.0,9.0), tvos(9.0,9.0
- (instancetype)initWithRequest:(NSURLRequest *)request delegate:(id)delegate;
- (void)useConnection {
    // 1.请求路径
    NSURL *url = [NSURL URLWithString:@"http://rap2api.taobao.org/app/mock/163155/gaoshilist"];
    // 2.创建请求对象
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    // 3.异步发送请求
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse * response, NSData *data, NSError *connectionError) {
        NSLog(@"length:%lu",(unsigned long)data.length);
    }];
}
二 普通任务和上传

NSURLSession针对下载/上传等复杂的网络操作提供了专门的解决方案,针对普通上传下载分别对应三种不同的网络请求任务:NSURLSessionDataTask, NSURLSessionUploadTaskNSURLSessionDownloadTask.。创建的task都是挂起状态,需要resume才能执行。

普通任务NSURLSessionDataTask实例代码

- (void)sessionDataTask {
    // 1.请求路径
    NSURL *url = [NSURL URLWithString:@"http://rap2api.taobao.org/app/mock/163155/gaoshilist"];
    // 2.创建请求对象
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    // 3.创建 session 对象
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    
    // 普通任务
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse * response, NSError *error) {
        if (error) {
            NSLog(@"NSURLSessionDataTaskerror:%@",error);
            return;
        }
        
        // 解析数据
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        NSLog(@"NSURLSessionDataTaskdic:%@",dic);
        
        //5.解析数据
        NSLog(@"NSURLSessionDataTask:%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
    }];
    
    // 执行 task
    [dataTask resume];
}

执行结果

image.png

上传任务时,NSURLSession设置 POST 请求的请求体

- (void)sessionDataTaskPost {
    // 1.请求路径
    NSURL *url = [NSURL URLWithString:@"http://rap2api.taobao.org/app/mock/163155/fankui"];
    // 2.创建请求对象
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    // 设置 post 请求方式
    request.HTTPMethod = @"POST";
    // 设置请求体
    request.HTTPBody = [@"" dataUsingEncoding:NSUTF8StringEncoding];
    
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:queue];
    
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (error) {
            NSLog(@"NSURLSessionDataTaskerror:%@",error);
            return;
        }
        
        //5.解析数据
        NSLog(@"NSURLSessionDataTask:%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
    }];
    
    [dataTask resume];
}

执行结果


image.png
三 下载任务方式

NSURLConnection下载文件时,先将整个文件下载到内存,然后再写入沙盒,如果文件比较大,就会出现内存暴涨的情况。

而使用NSURLSessionDownloadTask下载文件,会默认下载到沙盒中的tem文件夹中,不会出现内存暴涨的情况,但在下载完成后会将tem中的临时文件删除,需要在初始化任务方法时,在completionHandler回调中增加保存文件的代码。 以下代码是实例化网络下载任务时将下载的文件保存到沙盒的caches文件夹中:

NSURLConnection下载文件

- (void)downloadFile {
    // 1.创建下载路径
    NSURL *url = [NSURL URLWithString:@"http://dldir1.qq.com/qqfile/QQforMac/QQ_V5.4.0.dmg"];
    // 2.创建请求对象
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    // NSURLConnection发送异步Get请求,并实现相应的代理方法,该方法iOS9.0之后废除了。
    [NSURLConnection connectionWithRequest:request delegate:self];
}

#pragma mark - NSURLConnectionDataDelegate

// 接收到响应的时候:创建一个空的沙盒文件
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    NSLog(@"totalLength = %lld",response.expectedContentLength);
}

// 接收到具体数据:把数据写入沙盒文件中
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    NSLog(@"data length = %lu",(unsigned long)data.length);
}

// 下载完文件之后调用:关闭文件、清空长度
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSLog(@"下载完成");
}

打印结果

image.png image.png

NSURLSessionDownloadTask下载文件

- (void)sessionDownloadTask {
    // 1.请求路径
    NSURL *url = [NSURL URLWithString:@"http://www.pptbz.com/pptpic/UploadFiles_6909/201203/2012031220134655.jpg"];
    // 2.创建 session 对象
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    
    // 下载 task
    NSURLSessionDownloadTask *task = [session downloadTaskWithURL:url completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
        // 获取沙盒的 caches 路径
        NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"img.jpg"];
        // 生成 url 路径
        NSURL *url = [NSURL fileURLWithPath:path];
        // 将文件保存到指定文件目录下
        [[NSFileManager defaultManager] moveItemAtURL:location toURL:url error:nil];
    }];
    
    [task resume];
}

执行结果 - 断点调试

image.png image.png
四 请求方法的控制
  1. NSURLConnection实例化对象,实例化开始,默认请求就发送(同步发送),不需要调用start方法。而cancel 可以停止请求的发送,停止后不能继续访问,需要创建新的请求。

  2. NSURLSession有三个控制方法,取消(cancel),暂停(suspend),继续(resume),暂停后可以通过继续恢复当前的请求任务。默认不发送请求,需要手动调用resume方法

五 断点续传的方式
  1. NSURLConnection进行断点下载,通过设置访问请求的HTTPHeaderFieldRange属性,开启运行循环,NSURLConnection的代理方法作为运行循环的事件源,接收到下载数据时代理方法就会持续调用,并使用NSOutputStream管道流进行数据保存。

本文参考
NSURLSession与NSURLConnection区别


本文持续更新中,敬请期待。

上一篇下一篇

猜你喜欢

热点阅读