注:自己抽空帮别人随便写的一个demo,封装这种东西只能做参考,本篇主要写了自己用过的一些基本封装的方式
#import <Foundation/Foundation.h>
#import "AFNetworking.h"
#define API_MAIN @""
@interface AFMananger : NSObject
@property (nonatomic, strong)AFHTTPSessionManager *manager;
+ (instancetype)share;
+ (void)test1GETRequestWithReturnValeuBlock:(void (^)(id result, NSError *error))block;
+ (void)test2GETRequestWithReturnValeuBlock:(void (^)(id))block;
+ (void)test3GETRequestWithReturnValeuBlock:(void (^)(id result, NSError *error))block;
@end
#define request_method_post @"POST"
#define request_method_get @"GET"
#import "AFMananger.h"
#import <objc/runtime.h>
#import "AFTestMap.h"
#import "MJExtension.h"
@implementation AFMananger
+ (instancetype)share
{
static AFMananger *base = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
base = [AFMananger new];
NSURL *baseURL = [NSURL URLWithString:API_MAIN];
base.manager = [[AFHTTPSessionManager alloc] initWithBaseURL:baseURL];
//设置CA
[base.manager setSecurityPolicy:[AFMananger customSecurityPolicy]];
/**设置请求超时时间*/
base.manager.requestSerializer.timeoutInterval = 20;
/**设置相应的缓存策略*/
base.manager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
/**分别设置请求以及相应的序列化器*/
base.manager.requestSerializer = [AFHTTPRequestSerializer serializer];
AFJSONResponseSerializer * response = [AFJSONResponseSerializer serializer];
response.removesKeysWithNullValues = YES;
base.manager.responseSerializer = response;
/**复杂的参数类型 需要使用json传值-设置请求内容的类型*/
[base.manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
/**设置接受的类型*/
[base.manager.responseSerializer setAcceptableContentTypes:[NSSet setWithObjects:@"text/plain",@"application/json",@"text/json",@"text/javascript",@"text/html", nil]];
});
return base;
}
+ (AFSecurityPolicy*)customSecurityPolicy {
// /先导入证书
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"ssl.jikelife.com.comodo" ofType:@"cer"];//证书的路径
NSData *certData = [NSData dataWithContentsOfFile:cerPath];
// AFSSLPinningModeCertificate 使用证书验证模式
//AFSSLPinningModeNone 这个模式表示不做 SSL pinning,只跟浏览器一样在系统的信任机构列表里验证服务端返回的证书。若证书是信任机构签发的就会通过,若是自己服务器生成的证书,这里是不会通过的。
//AFSSLPinningModeCertificate 这个模式表示用证书绑定方式验证证书,需要客户端保存有服务端的证书拷贝,这里验证分两步,第一步验证证书的域名/有效期等信息,第二步是对比服务端返回的证书跟客户端返回的是否一致。
//AFSSLPinningModePublicKey 这个模式同样是用证书绑定方式验证,客户端要有服务端的证书拷贝,只是验证时只验证证书里的公钥,不验证证书的有效期等信息。只要公钥是正确的,就能保证通信不会被窃听,因为中间人没有私钥,无法解开通过公钥加密的数据。
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
// allowInvalidCertificates 是否允许无效证书(也就是自建的证书),默认为NO
// 如果是需要验证自建证书,需要设置为YES
securityPolicy.allowInvalidCertificates = YES;
//validatesDomainName 是否需要验证域名,默认为YES;
//假如证书的域名与你请求的域名不一致,需把该项设置为NO;如设成NO的话,即服务器使用其他可信任机构颁发的证书,也可以建立连接,这个非常危险,建议打开。
//置为NO,主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.google.com,那么mail.google.com是无法验证通过的;当然,有钱可以注册通配符的域名*.google.com,但这个还是比较贵的。
//如置为NO,建议自己添加对应域名的校验逻辑。
securityPolicy.validatesDomainName = NO;
securityPolicy.pinnedCertificates = [NSSet setWithObjects:certData, nil];
return securityPolicy;
}
//json转字典
+ (NSDictionary *)dictJsonValue:(NSString *)json {
NSError *error;
return [NSJSONSerialization JSONObjectWithData:[json dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error];
}
#pragma mark - 封装 (简单,不做数据处理)
/*@para 没做数据的处理
*requestURLString url接口
*parameter 参数
*method http请求类型
@return json数据
*/
+ (void)request1WithRequestURL:(NSString *)requestURLString
WithParameter:(NSDictionary *)parameter
httpMethod:(NSString*)method
WithReturnValeuBlock:(void (^)(id result, NSError *error)) block{
AFHTTPSessionManager *manager = [[AFMananger share]manager];
if ([method isEqualToString:request_method_post]) {
[manager POST:requestURLString parameters:parameter progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (responseObject) {
if (block) {
block(responseObject, nil);
}
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (block) {
block(nil, error);
}
}];
} else {
[manager GET:requestURLString parameters:parameter progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (requestURLString) {
if (block) {
block(responseObject, nil);
}
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (block) {
block(nil, error);
}
}];
}
}
#pragma mark - 封装二 (写的比较麻烦)
/*@para 使用时主要对AFBaseMap进行适量的更改
*requestURLString url接口
*parameter 参数
*className 要返回的接受数据类(如有,需继承AFBaseMap,此类包括code处理),
如果要接收数据不止code的处理,必须写其子类,完成数据操作。
*method http请求类型
@return object 如className不为空,则返回XMBaseMap子类对象,
否则返回XMBaseMap类对象
如果请求失败,返回AFBaseMap对象,但子类对象可以接收
*/
+ (void)request2WithRequestURL:(NSString *)requestURLString
WithParameter:(NSDictionary *)parameter
MapClass:(NSString*)className
httpMethod:(NSString*)method
WithReturnValeuBlock:(void (^)(id object)) block{
/**<,如果className为空,表示不需要其他映射>*/
Class cla;
if(className.length ==0){
cla = objc_getClass([@"AFBaseMap" UTF8String]);
}else{
cla = objc_getClass([className UTF8String]);
}
AFHTTPSessionManager *manager = [[AFMananger share]manager];
if([method isEqualToString:request_method_post]){
[manager POST:requestURLString parameters:parameter progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (responseObject) {
id json = [self dictJsonValue:responseObject];
__block id model = [[cla alloc] initWithJSON:json];
if (block) {
block (model);
}
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (block) {
__block id model = [[cla alloc] initWithError:error];
block(model);
}
}];
} else {
[manager GET:requestURLString parameters:parameter progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (responseObject) {
id json = [self dictJsonValue:responseObject];
__block id model = [[cla alloc] initWithJSON:json];
if (block) {
block (model);
}
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (block) {
__block id model = [[cla alloc] initWithError:error];
block(model);
}
}];
}
}
#pragma mark - 封装三(使用MJExtension.h)
/*@para 使用时需要根据情况封装父了类AFBaseModel,
*requestURLString url接口
*parameter 参数
*className 要返回的接受数据类(如有className,必须包含字典中的所有key值)
*method http请求类型
@return object 如className不为空,则返回字典
*/
+ (void)request3WithRequestURL:(NSString *)requestURLString
WithParameter:(NSDictionary *)parameter
MapClass:(NSString*)className
httpMethod:(NSString*)method
WithReturnValeuBlock:(void (^)(id result, NSError *error)) block{
Class cla;
if(className && className.length > 0){
cla = objc_getClass([className UTF8String]);
}
AFHTTPSessionManager *manager = [[AFMananger share]manager];
if([method isEqualToString:request_method_post]){
[manager POST:requestURLString parameters:parameter progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (responseObject) {
id dict = [self dictJsonValue:responseObject[@""]];
if (block) {
//字典转对象
block(cla?[cla mj_objectWithKeyValues:(NSDictionary *)dict]:dict, nil);
}
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (block) {
block(nil, error);
}
}];
} else {
[manager GET:requestURLString parameters:parameter progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (responseObject) {
id dict = [self dictJsonValue:responseObject];
if (block) {
block(cla?[cla mj_objectWithKeyValues:(NSDictionary *)dict]:dict, nil);
}
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (block) {
block(nil, error);
}
}];
}
}
#pragma mark - TEST
+ (void)test1GETRequestWithReturnValeuBlock:(void (^)(id result, NSError *error))block {
[self request1WithRequestURL:@"" WithParameter:nil httpMethod:request_method_get WithReturnValeuBlock:^(id result, NSError *error) {
if (block) {
block(result, error);
}
}];
}
+ (void)test2GETRequestWithReturnValeuBlock:(void (^)(id))block {
[self request2WithRequestURL:@"" WithParameter:nil MapClass:@"AFTestMap" httpMethod:request_method_get WithReturnValeuBlock:^(id object) {
if (block) {
block (object);
}
}];
}
+ (void)test3GETRequestWithReturnValeuBlock:(void (^)(id result, NSError *error))block {
[self request3WithRequestURL:@"" WithParameter:nil MapClass:@"AFTestModel" httpMethod:request_method_get WithReturnValeuBlock:^(id result, NSError *error) {
if (block) {
block(result, error);
}
}];
}
@end