美文网首页开发工具IOS 超级无敌基础应用
iOS网络请求工具oc版,swift版基于AFNetworkin

iOS网络请求工具oc版,swift版基于AFNetworkin

作者: 朱凯奇 | 来源:发表于2016-06-07 17:17 被阅读4081次

    1.为什么要封装

    对于AFNetworking的使用,相信大多数的公司都会用到,毕竟开源框架,安全高效.为了提高效率和代码的可维护性,我们就要二次封装AFN.

    2,以前遇到问题

    一个老项目,需要进行IPV6的迁移(虽然老版本的AFN也支持IPV6),但是方法变了,之前没有封装AFN,项目中用到AFN请求的地方有很多,接口上千,那么AFN出现的地方就上千个.更新AFN后,不支持老方法了,需要用新的方法,则需要替换上千个方法,这是个很大的工作量.这时封装的好处就体现出来了,只需改一处.

    3,如何解决的

    如标题所示,那就是二次封装AFNetworking

    重点在下面了


    AFNetworking的封装:OC版

    首先如下,别问为什么......

    cocoapods pod 'AFNetworking'


    注意点

    • 共享AFHTTPSessionManager对象,而不是每次新建SessionManager
      为什么要共享?给你们科普一下: HTTP协议是基于TCP协议的,所以在每次的HTTP请求之前,客户端和服务器端,都先需要经过TCP连接的三次握手,即每次请求之前,网络的数据都已经在客户端和服务器端之间来回了三次 如下图:
    Snip20160607_2.png

    所以这样做的目的就是提高请求效率,所以我是这么做的,请看下一步

    • ok,坐稳开车了

    1.创建单例请求对象

    创建一个类继承自AFHTTPSessionManager,如下:

    Snip20160607_1.png

    2.封装方法

    • 封装了几个常用的方法:get,post,上传,下载这几个方法,为什么用类方法?因为使用起来简单啊!!!
    
    @interface AFNHelper : AFHTTPSessionManager
    
    //单例
    + (AFNHelper *)sharedManager;
    
    /**
     *  get请求
     *
     *  @param url        接口url
     *  @param parameters 参数
     *  @param success    请求成功的block
     *  @param failure    请求失败的block
     */
    + (void)get:(NSString *)url parameter:(id )parameters success:(void(^)(id responseObject))success faliure:(void(^)(id error))failure;
    
    /**
     *  post请求
     *
     *  @param url        接口url
     *  @param parameters 参数
     *  @param success    请求成功的block
     *  @param failure    请求失败的block
     */
    + (void)post:(NSString *)url parameters:(id)parameters success:(void(^)(id responseObject))success faliure:(void(^)(id error))failure;
    /**
     *  post请求 不拼接基地址
     *
     *  @param url        接口url
     *  @param parameters 参数
     *  @param success    请求成功的block
     *  @param failure    请求失败的block
     */
    + (void)postNoBaseUrl:(NSString *)url parameters:(id)parameters success:(void(^)(id responseObject))success faliure:(void(^)(id error))failure;
    
    
    /**
     *  文件上传
     *
     *  @param url        接口url
     *  @param parameters 参数
     *  @param block      图片data
     *  @param success    请求成功的block
     *  @param failure    请求失败的block
     */
    + (void )post:(NSString *)url parameters:(id)parameters  constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block success:(void (^)(id responseObject))success faliure:(void (^)(id error))failure;
    
    
    /**
     *  文件下载
     *
     *  @param request       下载请求
     *  @param ProgressBlock 下载进度block
     *  @param savePath      储存路径
     *  @param failure       下载失败block
     */
    + (void)downloadTaskWithUrl:(NSString *)url progress:(void (^)(id downloadProgress))ProgressBlock savePath:(NSString *)savePath  completionHandler:(void (^)(NSURLResponse *response ,NSURL *filePath))completion  error:(void (^)(id error))failure;
    
    • .m的实现如下 BaseUrl是宏
    #import "AFNHelper.h"
    
    @implementation AFNHelper
    
    //单例实现
    + (AFNHelper *)sharedManager {
       
       static AFNHelper *handle = nil;
       
       static dispatch_once_t onceToken;
       dispatch_once(&onceToken, ^{
           handle = [AFNHelper manager];
         // 设置可接受的类型
           handle.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/plain",@"application/json",@"text/json",@"text/javascript",@"text/html",nil];
        
          
       });
       
       return handle;
    
    }
    
    
    //get请求
    + (void )get:(NSString *)url parameter:(id)parameters success:(void (^)(id responseObject))success faliure:(void (^)(id error))failure
    {
    
     [[AFNHelper sharedManager] GET:[BaseUrl stringByAppendingString:url] parameters:parameters progress:^(NSProgress * _Nonnull downloadProgress) {
           
       } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
           
           
           if(responseObject)  {
    
           success(responseObject);
    
           }
    
       } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
           
           failure(error);
           
       }];
       
    }
    
    //post请求
    + (void)post:(NSString *)url parameters:(id)parameters success:(void(^)(id responseObject))success faliure:(void(^)(id error))failure {
       
       [[AFNHelper sharedManager] POST:[BaseUrl stringByAppendingString:url] parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
           
       } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
           
           if(responseObject)  {
    
           success(responseObject);
    
           }
    
       } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
           
           failure(error);
           
       }];
       
    }
    
    
    //文件上传
    + (void )post:(NSString *)url parameters:(id)parameters  constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block success:(void (^)(id responseObject))success faliure:(void (^)(id error))failure{
       
      [[AFNHelper sharedManager] POST:[BaseUrl stringByAppendingString:url] parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
           block(formData);
           
       } progress:^(NSProgress * _Nonnull uploadProgress) {
           
       } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
           
             if(responseObject)  {
    
           success(responseObject);
    
           }
    
       } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
           
           failure(error);
           
       }];
     
    }
    
    
    //文件下载
    + (void)downloadTaskWithUrl:(NSString *)url progress:(void (^)(id downloadProgress))ProgressBlock savePath:(NSString *)savePath  completionHandler:(void (^)(NSURLResponse *response ,NSURL *filePath))completion  error:(void (^)(id error))failure{
       
    //创建请求
     NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[BaseUrl stringByAppendingString:url]]];
    
    //创建任务
      NSURLSessionDownloadTask *download =  [[AFNHelper sharedManager]  downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
          
          if (downloadProgress) {
              ProgressBlock(downloadProgress);
          }
          
           
       } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
           
           return  [NSURL fileURLWithPath:savePath];
           
       }completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
           
           if (!error) {
                 completion(response,filePath);
           }
           else {
           
               failure(error);
           
           }
         
           
       }];
    //开启任务
       [download resume];   
    }
    @end
    

    3.如何使用

    Snip20160607_7.png

    这样的话OC的基本上封装的实现就可以了

    AFNetworking的封装:swift版

    • swift的基本语法,我就不多说了,能用到这个的,肯定能看懂语法.....

    同上 cocoapods pod 'AFNetworking'

    1.创建单例请求对象

    创建一个类继承自AFHTTPSessionManager,如下:

    Snip20160607_3.png

    2.具体实现方法 也是常用的四个方法

     /**
         get请求
         
         - parameter urlString:  请求的url
         - parameter parameters: 请求的参数
         - parameter success:    请求成功回调
         - parameter failure:    请求失败回调
         */
        class func get(urlString:String,parameters:AnyObject?,success:((responseObject:AnyObject?) -> Void)?,failure:((error:NSError) -> Void)?) -> Void {
        
            AFNHelper.shareManager.GET(urlString, parameters: parameters, progress: { (progress) in
                
                }, success: { (task, responseObject) in
                    
                    //如果responseObject不为空时
                    if responseObject != nil {
                       
                        success!(responseObject:responseObject)
                    }
                    
                }) { (task, error) in
                    
                    failure!(error:error)
            }
        
            
        }
        
    
        /**
         post请求
         
         - parameter urlString:  请求的url
         - parameter parameters: 请求的参数
         - parameter success:    请求成功回调
         - parameter failure:    请求失败回调
         */
        class func post(urlString:String,parameters:AnyObject?,success:((responseObject:AnyObject?) -> Void)?,failure:((error:NSError) -> Void)?) -> Void {
            
            AFNHelper.shareManager.POST(urlString, parameters: parameters, progress: { (progress) in
                
                }, success: { (task, responseObject) in
                    
                    //如果responseObject不为空时
                    if responseObject != nil {
                        
                        success!(responseObject:responseObject)
                    }
                    
            }) { (task, error) in
                
                failure!(error:error)
            }
            
            
        }
        
        /**
         文件上传
         
         - parameter urlString:                 请求的url
         - parameter parameters:                请求的参数
         - parameter constructingBodyWithBlock: 文件data
         - parameter uploadProgress:            上传进度
         - parameter success:                   请求成功回调
         - parameter failure:                   请求失败回调
         */
        class func POST(urlString: String, parameters: AnyObject?, constructingBodyWithBlock:((formData:AFMultipartFormData) -> Void)?, uploadProgress: ((progress:NSProgress) -> Void)?, success: ((responseObject:AnyObject?) -> Void)?, failure: ((error: NSError) -> Void)?) -> Void {
            
            
            AFNHelper.shareManager.POST(urlString, parameters: parameters, constructingBodyWithBlock: { (formData) in
                
                constructingBodyWithBlock!(formData:formData)
                
                }, progress: { (progress) in
                    
                    uploadProgress!(progress:progress)
                    
                }, success: { (task, objc) in
                    
                    if objc != nil {
                        
                    success!(responseObject:objc)
                        
                    }
                }) { (task, error) in
                    
                    failure!(error:error)
            }
            
            
        }
        
        /**
         下载文件
         
         - parameter request:               请求的request
         - parameter downloadProgressBlock: 下载的进度
         - parameter savePath:              存储路径
         - parameter completionHandler:     完成后回调
         */
        class func downloadTaskWithRequest(request: NSURLRequest, downloadProgressBlock: ((downloadProgress :NSProgress) -> Void)?, savePath: String,completionHandler:((response:NSURLResponse, error:NSError?) -> Void)?) -> Void{
            
            //创建下载任务
            let task  =  AFNHelper.shareManager.downloadTaskWithRequest(request, progress: { (progress) in
                
                downloadProgressBlock!(downloadProgress:progress)
                
                }, destination: { (url, response) -> NSURL in
                    
                    
                    return NSURL(fileURLWithPath: savePath)
                }) { (response, url, error) in
                    
                    if (error == nil) {
                    
                        completionHandler!(response:response ,error:error)
                    
                    }
                    
                   
            }
            
            //开启下载
               task.resume()
          }
      
       
    
    

    3.如何使用

    截个图吧 如下:

    Snip20160607_4.png

    以上就是swift版本的AFN封装,看完之后觉得很简单吧


    4.总结

    以上只是我自己简单的封装,大家还可以继续完善.如有问题请指出.感谢您的阅读!

    相关文章

      网友评论

      • 当地比较英俊的男子:请问一下您是什么取消已经请求的网络
      • 6ea54dc08ca1:OC版 的demo链接 能不能发一下呢 谢谢
      • LinkStart:大神,如果把MBProgressHUD 的提示也封装在一起?我写的老是出问题。。
        sclcoder:不要这么做,耦合性太强了。而且MBProgressHUD是展示在UI层的
      • b85fd1d62f96:请教一下作者,如何把是否有网络的判断也封装在一起?
      • b85fd1d62f96:文件上传的方法报错,是不是没有返回值?
        朱凯奇:@舒大福 已经改啦,谢谢提醒
        朱凯奇:@shezengchi 没有返回值的,我改了
        舒大福:@shezengchi 对 我这也是提示缺少返回值~
      • 左左4143:为什么要继承于AFHTTPSessionManager呢
        朱凯奇:@Elephan_z 因为可以直接用manager对象
      • 鼻毛长长:AFNHelper我会根据业务再封装一层

      本文标题:iOS网络请求工具oc版,swift版基于AFNetworkin

      本文链接:https://www.haomeiwen.com/subject/fsmddttx.html