继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

AFNetworking封装-项目使用

30秒到达战场
关注TA
已关注
手记 286
粉丝 95
获赞 569

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

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

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

一.结构解析

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

https://img2.mukewang.com/5b274fd70001a2d106700136.jpg

 

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

vim Podfile     --->输入i

复制代码

platform :ios, '8.0'target "targetName" dopod '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

// 请求响应Blocktypedef 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

https://img2.mukewang.com/5b274fe700010c0f12420410.jpg

2.在API.m使用

https://img2.mukewang.com/5b274fef0001f20312340386.jpg

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

欢迎指正。

原文出处

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP