设为首页 加入收藏

TOP

AFNetworking二次封装的那些事(一)
2017-10-13 09:53:59 】 浏览:1099
Tags:AFNetworking 封装 那些

AFNetworking可是iOS网络开发的神器,大大简便了操作.不过网络可是重中之重,不能只会用AFNetworking.我觉得网络开发首先要懂基本的理论,例如tcp/ip,http协议,之后要了解web的请求和响应,会使用苹果自带的NSURLSession,最后是把AFNetworking的源码啃掉.

前言

一直以来网络开发用的都是前面同事基于AFNetworking二次封装好的框架,一直都没什么问题,也就没往深处去了解.然后公司开始新项目了,iOS端由我负责,这可是我的第一次啊,从零开始,构建整个项目.这是个挑战,内心还是有点小激动的.

轮子肯定是不用重复造的,网络框架就拿的老项目的,结果出现了两个问题.

  • 上传多张图片,服务端解析不了
  • 无文件上传, Content-Type还是multipart/form-data

为了解决这个问题,从就没用过的NSURLSession到http协议,追本溯源,终于解决了.

http协议

关于http协议的理论就不多讲了,主要就讲使用POST方法传递数据时,发送的请求头和请求体.

Content-Type

我们提交的数据是什么编码方式服务端是不知道的,其实我们完全可以自定义格式,只要服务端取到数据后能解析就可以了.
一般服务端语言如 php、python 等,以及它们的 framework,都内置了自动解析常见数据格式的功能。所以我们一般都用那几种常见的数据格式,数据格式就是请求头里的Content-Type,服务端根据Content-Type来解析请求体里的数据.
一般有四种最常见的方式:

  • application/x-www-form-urlencoded
    这是默认的方式,以key1=val1&key2=val2的方式进行编码.
    country=0&pro=1023&city=102301
  • multipart/form-data
    这个首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复, boundary 很长很复杂,一般有文件上传的时候用这种方法

      --Boundary+A675D0398A56493A
      Content-Disposition: form-data; name="photoFiles";    filename="photoFiles.jpeg"
      Content-Type: image/jpeg  
  • application/json
    这个非常常见了,感觉它适合格式支持比键值对复杂得多的结构化数据.
    {"country":0,"pro":1023,"city":102301}
  • text/xml
    它是一种使用 HTTP 作为传输协议,XML 作为编码方式的远程调用规范.
    移动端一般不会用它,太臃肿了,加的标签完全是浪费.

所以传文件用multipart/form-data.
application/json和application/x-www-form-urlencoded差不多,但是application/json数据更加直观,更适合结构更加复杂的数据.
我特地抓包了网易新闻等app,没有文件的情况下是application/json

NSMutableURLRequest设置

既然知道了请求头,请求体.那么给服务器端发送的请求按照上面的格式设置即可.

    //上传一张图片为例
    NSMutableURLRequest *request= [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:5.0f];
    request.HTTPMethod=@"POST";
   
    //数据体设置
    NSMutableData *dataM=[NSMutableData data];
    NSString *strTop=[NSString stringWithFormat:@"--%@\nContent-Disposition: form-data; name=\"file1\"; filename=\"%@\"\nContent-Type: %@\n\n",kBOUNDARY_STRING,fileName,@"image/jpg"];
    NSString *strBottom=[NSString stringWithFormat:@"\n--%@--",kBOUNDARY_STRING];
    NSString *filePath=[[NSBundle mainBundle] pathForResource:fileName ofType:nil];
    NSData *fileData=[NSData dataWithContentsOfFile:filePath];
    [dataM appendData:[strTop dataUsingEncoding:NSUTF8StringEncoding]];
    [dataM appendData:fileData];
    [dataM appendData:[strBottom dataUsingEncoding:NSUTF8StringEncoding]];

    
    //通过请求头设置
    [request setValue:[NSString stringWithFormat:@"%lu",(unsigned long)dataM.length] forHTTPHeaderField:@"Content-Length"];
    [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",kBOUNDARY_STRING] forHTTPHeaderField:@"Content-Type"];
    
    //设置数据体
    request.HTTPBody=dataM;

AFNetworking

AFNetworking就是基于NSMutableURLRequest,NSURLSession的封装,非常好用.
以POST为例,它有两个方法:

- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
                             parameters:(nullable id)parameters
                               progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
                                success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                                failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))f
首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇安装Cocoapods时候ERROR: While e.. 下一篇AFNetworking二次封装的那些事

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目