iOS-使用原生的网络请求--NSURLSession

203 阅读3分钟

###1.iOS原生网络请求的历史

NSURLConnection 作为 Core Foundation / CFNetwork 框架的 API 之上的一个抽象,在 2003 年就发布了,服务了成千上万的iOSMac OS程序后在 2013 的WWDC上,苹果推出了 NSURLConnection 的继任者:NSURLSession。(其实是用了那么久在 iPhone 和 iPad 上已经不够用了,所以苹果要对它进行重构)。 更改之后的NSURLConnection替换成了 NSURLSessionNSURLSessionConfiguration以及NSURLSessionTask的 3 个子类:NSURLSessionDataTaskNSURLSessionUploadTaskNSURLSessionDownloadTask

NSURLSessionTask的三个子类

废话不多说,如果要用原生的网络框架怎么进行网络请求呢?NSURLSession一般分别两部操作:第一,通过NSURLSession的实例创建task;第二,执行task

###2.Data task-GET请求

// 1,创建网络路径,get请求参数直接拼接在网页后面
    NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:@"http://www.baidu.com/api/login?yourname=%@&yourpwd=%@&btn=login",yourname,yourpwd]];
    // 2,创建网络请求
    NSURLRequest * request = [NSURLRequest requestWithURL:url];
    // 3,获取会话对象(NSURLSession的实例)
    NSURLSession * session = [NSURLSession sharedSession];
    /**
     4,通过NSURLSession的实例创建task
     
     request  方法内部会自动将 URL 包装成一个请求对象(默认是 GET 请求)
     completionHandler  完成之后的回调(成功或失败)
     param data     返回的数据(响应体)
     param response 响应头
     param error    错误信息
     */
    NSURLSessionDataTask * task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        //对从服务器获取到的数据data进行相应的处理,来到这里应该很熟悉了吧?
        NSDictionary * dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
        NSLog(@"%@----",dict);
    }];
    // 5,执行任务
    [task resume];

###3.Data task-POST请求

// 1,创建网络路径,get请求参数直接拼接在网页后面
    NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:@"http://www.baidu.com/api/login"]];
    // 2,创建可变网络请求
    NSMutableURLRequest * mutableRequest = [NSMutableURLRequest requestWithURL:url];
    // 2.1,修改请求方法
    mutableRequest.HTTPMethod = @"POST";
    // 2.2,设置请求体(设置参数)
    NSString * parameters = [NSString stringWithFormat:@"yourname=%@&yourpwd=%@",yourname,yourpwd];
    mutableRequest.HTTPBody = [parameters dataUsingEncoding:NSUTF8StringEncoding];
    // 3,获取会话对象(NSURLSession的实例)
    NSURLSession * session = [NSURLSession sharedSession];
    /**
     4,通过NSURLSession的实例创建task
     
     mutableRequest  方法内部会自动将 URL 包装成一个请求对象(默认是 GET 请求)
     completionHandler  完成之后的回调(成功或失败)
     
     param data     返回的数据(响应体)
     param response 响应头
     param error    错误信息
     */
    NSURLSessionDataTask * task = [session dataTaskWithRequest:mutableRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        //对从服务器获取到的数据data进行相应的处理,来到这里应该很熟悉了吧?
        NSDictionary * dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
        NSLog(@"%@----",dict);
    }];
    // 5,执行任务
    [task resume];

###4.Upload task

    // 1,创建网络路径
    NSURL * url = [NSURL URLWithString:@"http://www.baidu.com/api/upload"];
    // 2,创建可变网络请求,可以设置get和post上传请求,用post方法需要添加网络路径的请求体body,而在实际开发中,上传文件一般使用post方式,更加安全可靠。
    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url];
    // 3,上传的文件
    NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"upload.png"]];
    // 4,获取会话对象(NSURLSession的实例)
    NSURLSession * session = [NSURLSession sharedSession];
    // 5,通过NSURLSession的实例创建upload task
    NSURLSessionUploadTask * task = [session uploadTaskWithRequest:request fromData:data completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        //...
    }];
    // 6,执行任务
    [task resume];

###5.Download task

    // 1,创建网络路径
    NSURL * url = [NSURL URLWithString:@"http://sw.bos.baidu.com/sw-search-sp/software/09cdec345b1dd/QQMusicMac_5.2.dmg"];
    // 2,创建网络请求
    NSURLRequest * request = [NSURLRequest requestWithURL:url];
    // 3,获取会话对象(NSURLSession的实例)
    NSURLSession * session = [NSURLSession sharedSession];
    // 4,通过NSURLSession的实例创建download task,该方法的优点:内部已经完成了边接收数据边写沙盒的操作,解决了内存飙升的问题
    NSURLSessionDownloadTask * downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        //默认存储到临时文件夹 tmp 中,需要剪切文件到想要放的位置
        NSString * documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
        //存放下载文件的位置
        NSString * newFileLocation = [documentPath stringByAppendingPathComponent:response.suggestedFilename];
        //将文件移至目的位置
        [[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:newFileLocation] error:nil];
    }];
    // 5,执行任务
    [downloadTask resume];

###NSURLSessionDataDelegate

NSURLSession提供了block方式处理返回数据的简便方式,但是,如果项目需要在网络请求数据的过程中,要做进一步的处理的话,需要调用NSURLSession的代理方法。

开发只懂 AFN ?搞定 NSURLSession 才是硬道理 深入了解 NSURLSession 从 NSURLConnection 到 NSURLSession