• AFNetworking封装-项目使用


    本篇博客是接着上一篇AFNetworking源码解析的后续,如果想对AFNetworking源码有所了解。

    请读一下https://www.cnblogs.com/guohai-stronger/p/9191497.html

    YTKNetwork的源码详解:https://www.cnblogs.com/guohai-stronger/p/9194519.html

    这篇博客主要是对AFNetworking代码进行封装,也是自己在实际项目中所使用过的(对中小型企业或者项目)可直接使用,也会在github上传(偷偷窃喜一下,一直想在github上有所项目,一直没有时间),趁着端午几天有时间,给github贡献点自己力量。本篇读下来大约10-15分钟,欢迎指正。

    一.结构解析

    最核心(可直接拖拽到新项目中)

    (拓展cocoapods的拖入) 拖入之前,需要导入AFNetworking,最好利用cocoapods导入,cocoapods导入时

    vim Podfile     --->输入i
    platform :ios, '8.0'
    
    target "targetName" do
    
    pod 'AFNetworking'
    
    end

    (有一点在然后按Esc,并且输入“ :”号进入vim命令模式,然后在冒号后边输入wq)最后pod install。编译一下,拖入项目的类就好了,就不会编译错误。

    二.分类讲解

    1.Singleton

    #import <UIKit/UIKit.h>
    ////////////////////////////////////////////////////////////////////////////////
    // 申明和定义单例对象:
    // AS_SINGLETON( XxxClass );
    // DEF_SINGLETON( XxxClass );
    #undef    AS_SINGLETON
    #define AS_SINGLETON( __class ) 
    - (__class *)sharedInstance; 
    + (__class *)sharedInstance;
    
    #undef    DEF_SINGLETON
    #define DEF_SINGLETON( __class ) 
    - (__class *)sharedInstance 
    { 
        return [__class sharedInstance]; 
    } 
    + (__class *)sharedInstance 
    { 
        static dispatch_once_t once; 
        static __class * __singleton__; 
        dispatch_once( &once, ^{ __singleton__ = [[[self class] alloc] init]; } ); 
        return __singleton__; 
    }

    通过Singleton,来声明和定义单例对象。

    声明单例

    // 声明单例
    AS_SINGLETON(APIClient);

    定义单例

    // 定义单例
    DEF_SINGLETON(APIClient);

    2.APIClient.h

    (1)请求响应的状态

    // 请求响应的状态
    typedef NS_ENUM(NSInteger, ApiRequestStatusCode) {
        ApiRequestNotReachable = -2,    // 当前网络已断开
        ApiRequestErr          = -1,    // 请求出错
        ApiRequestOK           = 0,     // 请求成功
    };

    当时的请求响应状态只有三个,故定义一个枚举表示请求响应的状态。

    (2)请求的方法类型

    // 请求的方法类型
    typedef NS_ENUM(NSInteger, HttpMethod) {
        GET         = 0,
        POST        = 1,
        DELETE      = 2,
        PUT         = 3,
        PATH_GET    = 4, // GET请求,填充参数到url上,处理@"user/account/check/{phone}",{phone}这种情况
        QUERY_GET   = 5, // GET请求,填充query参数到url上,处理"?a=1&b=2"这种情况
    };

    (3)请求相应的block

    // 请求响应Block
    typedef void (^APIClientRequestResponse)(ApiRequestStatusCode requestStatusCode, id JSON);

    (4)通过设置代理拦截成功响应数据

    @protocol APIClientDelegate <NSObject>
    
    @required
    // 拦截成功请求响应数据进行处理
    - (void)handleSuccessRequest:(id)JSON completion:(void(^)(id aJSON))cb;
    
    @end

    在.h中还有一些方法属性

    // 为处理拦截的响应数据而设置的委托
    @property (nonatomic, weak) id<APIClientDelegate> delegate;
    
    // 声明单例
    AS_SINGLETON(APIClient);
    
    // 获取当前的网络状态类型(返回:0-No wifi or cellular(无网络), 1-2G, 2-3G, 3-4G, 4-LTE, 5-wifi)
    + (int)networkType;
    
    // 网络状态监听,应用当前是否有网络:有返回YES,没有返回NO
    + (void)networkReachableWithBlock:(void(^)(BOOL isReachable))block;
    
    // 发送请求,返回JSON格式的响应数据
    + (void)requestURL:(NSString *)urlString
            httpMethod:(HttpMethod)method
                params:(NSDictionary *)params
              response:(APIClientRequestResponse)response;
    
    // 取消掉所有网络请求
    + (void)cancelAllRequest;

    3.APIClient.m

    (1)创建请求管理对象

    @property (nonatomic, strong) AFHTTPSessionManager *manager;

    (2)获取当前的网络状态类型

    // 获取当前的网络状态类型(返回:0-No wifi or cellular(无网络), 1-2G, 2-3G, 3-4G, 4-LTE, 5-wifi)
    + (int)networkType {
        NSArray *subviews = [[[[UIApplication sharedApplication] valueForKey:@"statusBar"] valueForKey:@"foregroundView"]subviews];
        NSNumber *dataNetworkItemView = nil;
        
        for (id subview in subviews) {
            if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) {
                dataNetworkItemView = subview;
                break;
            }
        }
        int ret = 0;
        switch ([[dataNetworkItemView valueForKey:@"dataNetworkType"] integerValue]) {
            case 0:
                ret = 0;
                break;
            case 1:
                ret = 1;
                break;
            case 2:
                ret = 2;
                break;
            case 3:
                ret = 3;
                break;
            case 4:
                ret = 4;
                break;
            case 5:
                ret = 5;
                break;
            default:
                break;
        }
        return ret;
    }

    (3)网络状态监听,应用当前是否有网络

    // 网络状态监听,应用当前是否有网络
    + (void)networkReachableWithBlock:(void(^)(BOOL isReachable))block {
        [[AFNetworkReachabilityManager sharedManager] startMonitoring];
        
        [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
            switch (status) {
                case AFNetworkReachabilityStatusReachableViaWWAN:
                case AFNetworkReachabilityStatusReachableViaWiFi: {
                    if (block) {
                        block(YES);
                    }
                    break;
                }
                case AFNetworkReachabilityStatusNotReachable: {
                    if (block) {
                        block(NO);
                    }
                    break;
                }
                default:
                    break;
            }
        }];
        
        //结束监听
        //[[AFNetworkReachabilityManager sharedManager] stopMonitoring];
    }

    (3)请求最重要最核心的代码

    // 发送请求,返回JSON格式的响应数据
    + (void)requestURL:(NSString *)urlString
            httpMethod:(HttpMethod)method
                params:(NSDictionary *)params
              response:(APIClientRequestResponse)response {
        if ([APIClient networkType] > 0) {
            APIClient *client = [APIClient sharedInstance];
            if (!client.manager) {
                AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
                manager.requestSerializer.timeoutInterval = 30;
                manager.requestSerializer     = [AFHTTPRequestSerializer serializer];
                manager.responseSerializer    = [AFJSONResponseSerializer serializer];
                AFJSONResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];
                manager.responseSerializer = responseSerializer;
                manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html",@"text/plain",@"application/x-www-form-urlencodem", nil];
                
                
                client.manager = manager;
            }
            
            __weak typeof(self)weakSelf = self;
            switch (method) {
                case PATH_GET: {
                    urlString = [APIClient pathGet:urlString params:params];
    //                //LOG(@"PATH_GET http_url:%@",urlString);
                    [client.manager GET:urlString
                             parameters:nil
                               progress:nil
                                success:^(NSURLSessionDataTask * __unused task, id JSON) {
                                    __strong typeof(weakSelf)strongSelf = weakSelf;
                                    if (strongSelf) {
                                        [strongSelf handleSuccessRequest:JSON cb:response];
                                    }
                                }
                                failure:^(NSURLSessionDataTask *__unused task, NSError *error) {
                                    if (response) {
                                        response(ApiRequestErr, nil);
                                    }
                                }];
                    break;
                }
                case QUERY_GET: {
                    urlString = [APIClient queryGet:urlString params:params];
                    //LOG(@"QUERY_GET http_url:%@",urlString);
                    [client.manager GET:urlString
                             parameters:nil
                               progress:nil
                                success:^(NSURLSessionDataTask * __unused task, id JSON) {
                                    __strong typeof(weakSelf)strongSelf = weakSelf;
                                    if (strongSelf) {
                                        [strongSelf handleSuccessRequest:JSON cb:response];
                                    }
                                }
                                failure:^(NSURLSessionDataTask *__unused task, NSError *error) {
                                    if (response) {
                                        response(ApiRequestErr, nil);
                                    }
                                }];
                    break;
                }
                case GET: {
    //                //LOG(@"GET http_url:%@",urlString);
                    [client.manager GET:urlString
                      parameters:nil
                        progress:nil
                         success:^(NSURLSessionDataTask * __unused task, id JSON) {
                             __strong typeof(weakSelf)strongSelf = weakSelf;
                             if (strongSelf) {
                                 [strongSelf handleSuccessRequest:JSON cb:response];
                             }
                         }
                         failure:^(NSURLSessionDataTask *__unused task, NSError *error) {
                             if (response) {
                                 response(ApiRequestErr, nil);
                                 //LOG(@"GET http_url:%@",urlString);
                             }
                         }];
                    break;
                }
                case POST: {
    //                //LOG(@"POST http_url:%@",urlString);
                    [client.manager POST:urlString
                       parameters:params
                         progress:nil
                          success:^(NSURLSessionDataTask * __unused task, id JSON) {
                              __strong typeof(weakSelf)strongSelf = weakSelf;
                              if (strongSelf) {
                                  [strongSelf handleSuccessRequest:JSON cb:response];
                              }
                          }
                          failure:^(NSURLSessionDataTask *__unused task, NSError *error) {
    //                          //LOG(@"%@",error);
                              if (response) {
                                  response(ApiRequestErr, nil);
                              }
                          }];
                    break;
                }
                case DELETE: {
                    //LOG(@"DELETE http_url:%@",urlString);
                    [client.manager DELETE:urlString
                         parameters:nil
                            success:^(NSURLSessionDataTask * __unused task, id JSON) {
                                __strong typeof(weakSelf)strongSelf = weakSelf;
                                if (strongSelf) {
                                    [strongSelf handleSuccessRequest:JSON cb:response];
                                }
                            }
                            failure:^(NSURLSessionDataTask *__unused task, NSError *error) {
                                if (response) {
                                    response(ApiRequestErr, nil);
                                }
                            }];
                    break;
                }
                case PUT: {
                    //LOG(@"PUT http_url:%@",urlString);
                    [client.manager PUT:urlString
                      parameters:params
                         success:^(NSURLSessionDataTask * __unused task, id JSON) {
                             __strong typeof(weakSelf)strongSelf = weakSelf;
                             if (strongSelf) {
                                 [strongSelf handleSuccessRequest:JSON cb:response];
                             }
                         }
                         failure:^(NSURLSessionDataTask *__unused task, NSError *error) {
                             if (response) {
                                 response(ApiRequestErr, nil);
                             }
                         }];
                    break;
                }
            }
        } else { // 没有连接网络
            if (response)
                response(ApiRequestNotReachable, nil);
        }
    }

    (4)统一处理响应数据

    // 统一处理响应数据
    + (void)handleSuccessRequest:(id)JSON cb:(void(^)(ApiRequestStatusCode requestStatusCode, id JSON))cb {
        APIClient *client = [APIClient sharedInstance];
        if (client.delegate && [client.delegate respondsToSelector:@selector(handleSuccessRequest:completion:)]) {
            [client.delegate handleSuccessRequest:JSON
                                  completion:^(id aJSON) {
                                      if (cb) {
                                          cb(ApiRequestOK, aJSON);
                                      }
                                  }];
        } else {
            if (cb) {
                cb(ApiRequestOK, JSON);
            }
        }
    }

    (5)参数拼接

    // 填充参数到url上,处理@"user/account/check/{phone}",{phone}这种情况
    + (NSString *)pathGet:(NSString *)uri
                   params:(NSDictionary *)params {
        if (nil == uri|| nil == params || params.count <= 0) {
            return  uri;
        }
        for (NSString *key in params) {
            NSString *key2 = [NSString stringWithFormat:@"{%@}",key];
            if ([uri rangeOfString:key2].location != NSNotFound) {
                uri = [uri stringByReplacingOccurrencesOfString:key2 withString:params[key]];
            }
        }
        return [uri stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    }
    
    // 填充query参数到url上,处理"?a=1&b=2"这种情况
    + (NSString *)queryGet:(NSString *)uri
                    params:(NSDictionary *)params {
        if (nil == uri || nil == params || params.count <= 0) {
            return  uri;
        }
        NSMutableString *tmpUri = [NSMutableString stringWithString:uri];
        int i = 0;
        for (NSString *key in params) {
            if (i == 0) {
                [tmpUri appendFormat:@"?%@=%@",key, params[key]];
            } else {
                [tmpUri appendFormat:@"&%@=%@",key, params[key]];
            }
            i++;
        }
        return [tmpUri stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];;
    }

    (6)取消所有网络请求

    // 取消掉所有网络请求
    + (void)cancelAllRequest {
        APIClient *client = [APIClient sharedInstance];
        if (client.manager) {
            if (client.manager.operationQueue) {
                [client.manager.operationQueue cancelAllOperations];
            }
        }
    }

    上面就是代码的主要封装,可以应对中小型企业和App的要求。

    三.使用

    1.新建API.h继承NSObject

    2.在API.m使用

    3.在控制器里面调用如下

     WS(weakSelf);
        if ([APIClient networkType] > 0){
            //获取个人界面的信息
            [API1 getEvaluateMeDataWithCB:^(ApiRequestStatusCode requestStatusCode, id JSON) {
                switch (requestStatusCode) {
                    case ApiRequestOK: {
                        //正确解析json,以及UI处理break;
                        }
                    }
                    case ApiRequestErr:
                        [MBProgressHUD showError:kErrTip];
                        break;
                    case ApiRequestNotReachable:
                        [MBProgressHUD showError:kNotReachableTip];
                        break;
                    default:
                        break;
                }
            }];
        }else{
            [MBProgressHUD showError:kNotReachableTip];
        }

    上面就是针对AFNetworking的简单封装,可以满足网络请求的封装。

    本次代码的demo已上传git。github地址https://github.com/zxy1829760/testAF

    欢迎指正!!!

    下一篇讲述另一篇关于网络封装的YTKNetwork源码解析。

  • 相关阅读:
    bzoj1951 [Sdoi2010]古代猪文
    bzoj2693 jzptab
    数学一本通第三章总结
    poj1019 Number Sequence
    SGU179 Brackets light
    字母组合2
    字母组合
    Java基础知识强化之集合框架笔记09:Collection集合迭代器使用的问题探讨
    Java基础知识强化之集合框架笔记08:Collection集合自定义对象并遍历案例(使用迭代器)
    Java基础知识强化之集合框架笔记07:Collection集合的遍历之迭代器遍历
  • 原文地址:https://www.cnblogs.com/guohai-stronger/p/9193465.html
Copyright © 2020-2023  润新知