您的位置:首页 > 理论基础 > 计算机网络

iOS - 简述二次封装AFN,设置请求头,https安全策略

2016-10-29 19:57 405 查看
以前都是直接复制粘贴二次封装好的代码 , 现在都忘了怎么写 . 恰好当前项目要用到请求头 , 在网上学习了一下 , 统一敲了一遍 .自从到了现在公司 , 才发现要学的东西太多了 , 当然 , 有个好的老大比什么都重要… 能学到不少的东西…

创建两个类 , 一个类用于封装AFN , 一个类用作返回值模型

response模型类

#import <Foundation/Foundation.h>

@interface netWorkResponse : NSObject

//实际远不止这些属性
@property (assign, nonatomic) BOOL isSuccess;
@property (strong, nonatomic) NSError *error;
@property (strong, nonatomic) id data;
@property (assign, nonatomic) NSInteger statusCode;

//单例
+ (instancetype)shareInstance;

@end


#import "netWorkResponse.h"

static netWorkResponse *responseModel = nil;

#pragma mark - 模型类
/**
模型类
*/
@implementation netWorkResponse

+ (instancetype)shareInstance
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{

responseModel = [[netWorkResponse alloc]init];
});
return responseModel;
}

@end


封装网络请求类

#import "NetWorkTool.h"
#import "AFNetworking.h"

#pragma mark - 网络请求manager
/**
继承AFHTTPSessionManager 单例
*/
@interface AFHttpManager  : AFHTTPSessionManager

@end


manager参数配置

继承AFN原生httpmanager , 用于生成单例 , 配置请求的一些参数 , 比如 基地址 , 请求头 , 接收返回类型等

@implementation AFHttpManager

//设置单例
+ (AFHttpManager *)sharedManager
{
static AFHttpManager *httpManager = nil;

static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{

//如果设置了 服务器主地址 , 那么后面请求就不用拼接了 .
//当然我试了下这里加主地址 , 请求时又拼接了主地址 , 也访问成功了.
//    AFHttpManager *httpManager = [AFHTTPSessionManager alloc]initWithBaseURL:<#(nullable NSURL *)#>

httpManager = [AFHttpManager manager];

//        httpManager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/html", @"text/json", @"text/javascript",@"text/plain",@"image/gif", nil];

//现在貌似不用写接收类型了,试了试访问@"https://baidu.com",提示不能接收@"text/html"类型 , 我写下述一句 , 和写上面接收类型一样的效果
httpManager.responseSerializer = [AFHTTPResponseSerializer serializer];

//设置访问请求头 , 请求头是服务器限制用来限制访问而要求客户端添加的一个标识 . 就好比是一个暗号 . 如果服务端没做要求 , 不用加请求头也可以
[httpManager.requestSerializer setValue:@"doAction" forHTTPHeaderField:@"te_method"];
[httpManager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[httpManager.requestSerializer setValue:@"2.2" forHTTPHeaderField:@"te_version"];
[httpManager.requestSerializer setValue:@"moa" forHTTPHeaderField:@"party_id"];
});

//设置安全策略 (https) ,数字证书验证,此段具体实现 , 后期更新 ...
httpManager.securityPolicy = [httpManager customSecurityPolicy];

return httpManager;
}


下述证书验证方法转自cocoachina

http://www.cocoachina.com/bbs/read.php?tid-325551-page-2.html


- (AFSecurityPolicy*)customSecurityPolicy
{
// /先导入证书
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"**.cer" ofType:@""];//证书的路径
NSData *certData = [NSData dataWithContentsOfFile:cerPath];

// AFSSLPinningModeCertificate 使用证书验证模式
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 setWithObject:certData];

return securityPolicy;
}
@end


封装工具类实现

当访问服务器成功或失败后 , 将信息赋值给模型 , 统一传回 ,这样比较整洁一些 , 不会很凌乱

/**
封装的网络工具类
*/

@implementation NetWorkTool

//此处就仅以一个get请求为例 , post请求大同小异
+ (void)getRequestWithUrl:(NSString *)urlString parameters:(id)parameters response:(response)callback
{
//响应对象
netWorkResponse *response = [netWorkResponse shareInstance];

[[AFHttpManager sharedManager]GET:urlString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {

response.isSuccess = YES;
//将responseObject 数据赋值给 response , 操作省略
callback(response);

} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

response.isSuccess = NO;
response.error = error; //此处错误可根据服务器返回状态 , 自行返回具体的错误
callback(response);

}];
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ios