从NSURLSession到AFNetworking再到自己封装一个网络框架

来源:互联网 发布:用友软件联系方式 编辑:程序博客网 时间:2024/05/20 04:30

从NSURLSession讲起

首先从七层网络协议讲起:物理层 –> 数据链路层 –> 网络层 –> 传输层 –> 会话层 –> 表示层 –> 应用层,我们说的NSURLSession是会话层。

常用术语讲解:
NSURL:请求地址,定义一个网络资源路径。一个请求地址由协议、主机地址、路径、参数(非必须)构成。

NSURLRequest:网络请求,根据请求地址建立一个请求。

NSMutableURLRequest:可变网络请求,可以设置请求头等信息。

NSURLSessionTask经典图:
NSURLSessionDataTask用来处理一般的网络请求,它的子类NSURLSessionUploadTask用来处理上传网络请求,NSURLSessionDownloadTask用来处理下载的网络请求

Task

Demo链接下载 密码: 66is

1.block解析返回GET数据

//请求路径NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];NSURLSession *session = [NSURLSession sharedSession];NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {        //解析返回数据}];[dataTask resume];

2.block解析返回POST数据

//请求路径NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];NSMutableURLRequest *mulRequest = [[NSMutableURLRequest alloc] initWithURL:url];//设置请求方法和请求体mulRequest.HTTPMethod = @"POST";mulRequest.HTTPBody = [@"username=zhaoliying&password=1314" dataUsingEncoding:NSUTF8StringEncoding];NSURLSession *session = [NSURLSession sharedSession];NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:mulRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {        //解析返回数据}];[dataTask resume];

3.代理解析返回数据

- (void)postDelegateNetWork {    NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];    NSMutableURLRequest *mulRequest = [[NSMutableURLRequest alloc] initWithURL:url];    mulRequest.HTTPMethod = @"POST";    mulRequest.HTTPBody = [@"username=zhaoliying&password=1314" dataUsingEncoding:NSUTF8StringEncoding];    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:mulRequest];    [dataTask resume];}#pragma NSURLSessionDelegate- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(nonnull NSURLResponse *)response completionHandler:(nonnull void (^)(NSURLSessionResponseDisposition))completionHandler {    //接收到服务器响应的时候调用    completionHandler(NSURLSessionResponseAllow);}- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {    //接收到服务器返回数据的时候调用}- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {    //解析服务器返回数据}

4.下载文件

NSURL *url = [NSURL URLWithString:@"https://music.baidu.com/song/100575177/小薇.mp3"];NSURLRequest *request = [NSURLRequest requestWithURL:url];NSURLSession *session = [NSURLSession sharedSession];NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {        //默认存储到临时文件夹中,需要将文件移动到其它位置NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];[[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:path] error:nil];}];[downloadTask resume];

5.简单上传

NSURL *url = [NSURL URLWithString:@"https://www.baidu.com/baiduyun"];NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];request.HTTPMethod = @"POST";UIImage *image = [UIImage imageNamed:@"zhaoliying.png"];NSData *data = UIImagePNGRepresentation(image);NSURLSession *session = [NSURLSession sharedSession];NSURLSessionUploadTask *dataTask = [session uploadTaskWithRequest:request fromData:data completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {}];[dataTask resume];

6.拼接表单实现文件上传

- (void)uploadNetWorkSecond {    NSURL *url = [NSURL URLWithString:@"https://www.baidu.com/baiduyun"];    NSMutableURLRequest *mulRequest = [NSMutableURLRequest requestWithURL:url];    mulRequest.HTTPMethod = @"POST";    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data;boundary=%@",@"boundary"];    [mulRequest setValue:contentType forHTTPHeaderField:@"Content-Type"];    //拼接表单,filePath:要上传文件路径,formName:表单控件名称,与服务器一致,newName:上传后的文件名称    NSData *data = [self setFilePath:@"/users/yimiyangguang/Desktop/zhaoliying.png" formName:@"file" newName:@"newzhaoliying.png"];    mulRequest.HTTPBody = data;    [mulRequest setValue:[NSString stringWithFormat:@"%lu",data.length] forHTTPHeaderField:@"Content-Length"];    NSURLSession *session = [NSURLSession sharedSession];    NSURLSessionUploadTask *dataTask = [session dataTaskWithRequest:mulRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {    }];    [dataTask resume];}- (NSData *)setFilePath:(NSString *)filePath formName:(NSString *)formName newName:(NSString *)newName {    NSMutableData *data = [NSMutableData data];    NSURLResponse *response = [self getLocalFileResponse:filePath];    NSString *fileType = response.MIMEType;    //表单拼接    NSMutableString *headerStr = [NSMutableString string];    [headerStr appendFormat:@"--%@\r\n",@"boundary"];    [headerStr appendFormat:@"Content-Disposition: form-data; name=%@; filename=%@\r\n",formName,newName];    [headerStr appendFormat:@"Content-Type: %@\r\n\r\n",fileType];    [data appendData:[headerStr dataUsingEncoding:NSUTF8StringEncoding]];    NSData *fileData = [NSData dataWithContentsOfFile:filePath];    [data appendData:fileData];    NSMutableString *footerStr = [NSMutableString stringWithFormat:@"\r\n--%@--\r\n",@"boundary"];    [data appendData:[footerStr dataUsingEncoding:NSUTF8StringEncoding]];    return data;}//根据本地文件路径,对本地文件进行处理- (NSURLResponse *)getLocalFileResponse:(NSString *)filePath {    filePath = [filePath stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]];    NSURL *url = [NSURL fileURLWithPath:filePath];    NSURLRequest *request = [NSURLRequest requestWithURL:url];    __block NSURLResponse *LocalResponse = nil;    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);    NSURLSession *session = [NSURLSession sharedSession];    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {        LocalResponse = response;        dispatch_semaphore_signal(semaphore);    }];    [dataTask resume];    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);    return LocalResponse;}

经过AFNetworking的洗礼

我们之前讲过AFN的概况介绍,今天我们浅析一下AFN的封装思路,并从另一个角度讲解AFN中的技术点。

我们首先从AFNetworking的大体结构说起:
1.我们封装一个网络框架,首先需要一个类来检测当前网络环境(AFNetworkReachabilityManager):AFN提供了四种网络状态–未知、蜂窝、wifi、无网络。如果网络环境发生了改变,需要及时进行通知。
2.我们需要封装一个类来提供安全策略(AFSecurityPolicy):AFN提供了三种安全策略–公钥、证书、无。
3.我们需要封装一个类来提供请求序列化(AFURLRequestSerialization):缓存策略、cookie使用、超时时间、请求头处理等,并根据不同条件返回请求实例。
4.我们需要封装一个类来提供响应序列化(AFURLResponseSerialization):可接受的状态码、可接受的Content-Type类型、是否有效的响应,实例化响应实例。处理json、xml和其他潜在类型的类。
5.我们需要封装一个类(AFURLSessionManager),将上面的四个类进行应用,并提供网络会话及相关操作。
6.为了更好的进行HTTP的细节处理,提供子类(AFHTTPSessionManager),分别用来处理GET、POST、HEAD、PUT、PATCH、DELET方法。

原创粉丝点击