AFNetworking封装-项目使用

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

请读一下https://www.cnblogs.com/guohai-stronger/p/9191497.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

欢迎指正。

原文地址:https://www.cnblogs.com/guohai-stronger/p/9193465.html

时间: 2024-11-05 23:37:46

AFNetworking封装-项目使用的相关文章

AFNetWorking封装请求数据

// //  YXYAppDelegate.m //  AFNetWorking封装 // //  Created by lanjiying on 14/11/20. //  Copyright (c) 2014年 lanjiying. All rights reserved. // #import <Foundation/Foundation.h> #import "AFNetworking.h" typedef void(^CompletionLoad)(NSObjec

Android--带你一点点封装项目 MVP+BaseActivity+Retrofit+Dagger+RxJava(三)

1,这一篇博客是和大家一起来封装我们最后的Dagger2,其实之前也写过关于简单的Dagger2,这里是地址,完全没了解的同学可以先去看一下这篇,感谢很多小伙伴一直在耐心的等待这一篇 2,Dagger2可以说是些技术中最难上手的,不过把主要的四个注解理解到位了,基本上就可以用了: @Inject Inject主要有两个作用,一个是使用在构造函数上,通过标记构造函数让Dagger2来使用(Dagger2通过Inject标记可以在需要这个类实例的时候来找到这个构造函数并把相关实例new出来)从而提供

AFNetworking封装思路简析

http://blog.csdn.net/qq_34101611/article/details/51698473 一.AFNetworking的发展 1. AFN 1.0版本 AFN 的基础部分是 AFURLConnectionOperation,一个 NSOperation 子类,实现了 基于NSURLConnection 相关的delegate+blocks,网络部分是由 NSURLConnection 完成,然后利用 NSOperation 的 state(isReady→isExecu

AFNetworking封装的网络请求

#import "AFNetworking.h" typedef void(^SuccessBlock)(AFHTTPRequestOperation * operation, id responseObj); typedef void(^FailBlock)(NSError * error, id responseObj); #import <Foundation/Foundation.h> @interface NetworkingManager : NSObject

基于AFNetworking封装的网络请求工具类

前提,导入AFNetworking框架 关于修改AFN源码:通常序列化时做对text/plan等的支持时,可以一劳永逸的修改源代码,在acceptableContentTypes中修改即可. GGRequest.h 1 #import <Foundation/Foundation.h> 2 3 @interface GGRequest : NSObject 4 /** 5 * 网络请求方法 6 * 7 * @param url 将要访问的链接 8 * @param param 传入的参数 9

单例:用AFNetworking封装举例

创建单例的方式 1 import AFNetworking 2 3 class NetworkTools: AFHTTPSessionManager { 4 5 //let是线程安全的 6 //使用单例实例只需要拿到NetworkTools这个类取出来这个常量属性就可以拿到单例 7 static let shareInstance: NetworkTools = NetworkTools() 8 9 } 具体使用方式 1 import UIKit 2 3 class ViewController

自己总结的 iOS ,Mac 开源项目以及库,知识点------持续更新

自己在 git  上看到一个非常好的总结的东西,但是呢, fork  了几次,就是 fork  不到我的 git 上,干脆复制进去,但是,也是认真去每一个每一个去认真看了,并且也是补充了一些,感觉非常棒,所以好东西要分享,为啥用 CN 博客,有个好处,可以随时修改,可以持续更新,不用每次都要再发表,感觉这样棒棒的 我们 自己总结的iOS.mac开源项目及库,持续更新.... github排名 https://github.com/trending,github搜索:https://github.

iOS、mac开源项目及库汇总

UI 下拉刷新 EGOTableViewPullRefresh – 最早的下拉刷新控件. SVPullToRefresh – 下拉刷新控件. MJRefresh – 仅需一行代码就可以为UITableView或者CollectionView加上下拉刷新或者上拉刷新功能.可以自定义上下拉刷新的文字说明.具体使用看“使用方法”. (国人写) XHRefreshControl – XHRefreshControl 是一款高扩展性.低耦合度的下拉刷新.上提加载更多的组件.(国人写) CBStoreHou

最全面的iOS和Mac开源项目和第三方库汇总

UI 下拉刷新 EGOTableViewPullRefresh – 最早的下拉刷新控件. SVPullToRefresh – 下拉刷新控件. MJRefresh – 仅需一行代码就可以为UITableView或者CollectionView加上下拉刷新或者上拉刷新功能.可以自定义上下拉刷新的文字说明.具体使用看“使用方法”. (国人写) XHRefreshControl – XHRefreshControl 是一款高扩展性.低耦合度的下拉刷新.上提加载更多的组件.(国人写) CBStoreHou