iOS-在AFN基础上进行网络请求的封装
网络请求的思路:如果请求成功的话AFN的responseObject就是解析好的。
1发送网络请求;get/post/或者别的 带上URL,需要传的参数
2判断后台网络状态码有没有请求成功;
3 请求成功:解析数据,刷新页面
4请求失败做处理
VPKCResponse.h
VPKCResponse.m
VPKCRequestManager.h
VPKCRequestManager.m
定义两个文件继承NSObject。
VPKCResponse.h
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSInteger, VPKCHttpStatusCode) {
/// 业务正常处理
VPKCStatusCode_OK = 200,
/// 袋鼠家业务错误,返回错误码和错误信息
VPKCStatusCode_Accepted = 202,
/// 上行参数不符合定义,比较必须参数、json格式、数据类型等
VPKCStatusCode_BadRequest = 400,
/// 权限不够,hmac问题
VPKCStatusCode_Unauthorized = 401,
/// 请求的uri不符合协议规定,在服务器无法找到对应的处理器
VPKCStatusCode_NotFound = 404,
/// 服务器异常
VPKCStatusCode_InternalServerError = 500,
/// 接口对应的服务未部署
VPKCStatusCode_BadGateway = 502,
};
@interface VPKCResponse : NSObject
/// 请求返回 responseObject
@property(copy, nonatomic) id responseObject;
//
/// 请求头信息
@property (copy, nonatomic) id headerFields;
//
/// AFNetworking返回错误信息
@property(strong, nonatomic) NSError *error;
//
//
///// 服务器状态码
@property (strong, nonatomic) NSNumber *status;
///// 202状态错误码
@property (strong, nonatomic) NSNumber *errorCode;
//
///// 202状态错误描述信息
@property (copy, nonatomic) NSString *errorDescription;
//
///// 弹框显示内容
@property (nonatomic, copy) NSString *content;
@end
#pararmmark
VPKCRequestManager.h
#import <Foundation/Foundation.h>
#import "VPKCResponse.h"
@interface VPKCRequestManager : NSObject
/// 获取当前网络是否可用
@property (assign, nonatomic, readonly) BOOL reachable;
/// 单利
+ (VPKCRequestManager *)sharedRequest;
/// 取消当前请求任务
- (void)cancelCurrentTask;
/// 取消所有请求任务
- (void)cancelAllTask;
/// GET
+ (VPKCRequestManager *)GET:(NSString *)url
withParame:(NSDictionary *)parame
withComplete:(void(^)(VPKCResponse *responseObj))result;
/// POST
+ (VPKCRequestManager *)POST:(NSString *)url
withParame:(NSDictionary *)parame
withComplete:(void(^)(VPKCResponse *responseObj))result;
/// PUT
+ (VPKCRequestManager *)PUT:(NSString *)url
withParame:(NSDictionary *)parame
withComplete:(void(^)(VPKCResponse *responseObj))result;
/// PATCH
+ (VPKCRequestManager *)PATCH:(NSString *)url
withParame:(NSDictionary *)parame
withComplete:(void(^)(VPKCResponse *responseObj))result;
/// DELETE
+ (VPKCRequestManager *)DELETE:(NSString *)url
withParame:(NSDictionary *)parame
withComplete:(void(^)(VPKCResponse *responseObj))result;
@end
VPKCRequestManager.m
#import "VPKCRequestManager.h"
#import "VPKCUtils.h"
#import "AFNetworkActivityIndicatorManager.h"
#import "AFNetworking.h"
typedef NS_ENUM(NSInteger , VPKCRequestMethod) {
VPKCRequestMethodGet,
VPKCRequestMethodPost,
VPKCRequestMethodPut,
VPKCRequestMethodDelete,
VPKCRequestMethodPatch,
VPKCRequestMethodHead,
};
const NSString *methodStirng[] = {
[VPKCRequestMethodGet] = @"GET",
[VPKCRequestMethodPost] = @"POST",
[VPKCRequestMethodHead] = @"HEAD",
[VPKCRequestMethodPut] = @"PUT",
[VPKCRequestMethodDelete] = @"DELETE",
[VPKCRequestMethodPatch] = @"PATCH",
};
@interface VPKCRequestManager ()
@property (strong, nonatomic) AFHTTPSessionManager *sessionManager;
@property (strong, nonatomic) NSURLSessionDataTask *sessionDataTask;
/// 网络是否可用
@property (assign, nonatomic, readwrite) BOOL reachable;
//
/// 当前任务ID
@property (assign, nonatomic) NSInteger taskIdentifier;
//
//
//
/// 请求地址(前半段)
@property (strong, nonatomic) NSString *requestBaseUrl;
// 请求地址(后半段)
@property (copy, nonatomic) NSString *requestApiUrl;
/// 请求参数
@property (strong, nonatomic) NSDictionary *requestParame;
/// 请求方式
@property (assign, nonatomic) VPKCRequestMethod requestMethod;
@end
@implementation VPKCRequestManager
#pragma mark ---------------------------------------------------------------
/// GET
+ (VPKCRequestManager *)GET:(NSString *)url
withParame:(NSDictionary *)parame
withComplete:(void(^)(VPKCResponse *responseObj))result {
return [self requestConfigWithUrl:url withParame:parame withMethod:VPKCRequestMethodGet withComplete:result];
}
/// POST
+ (VPKCRequestManager *)POST:(NSString *)url
withParame:(NSDictionary *)parame
withComplete:(void(^)(VPKCResponse *responseObj))result {
return [self requestConfigWithUrl:url withParame:parame withMethod:VPKCRequestMethodPost withComplete:result];
}
/// PUT
+ (VPKCRequestManager *)PUT:(NSString *)url
withParame:(NSDictionary *)parame
withComplete:(void(^)(VPKCResponse *responseObj))result {
return [self requestConfigWithUrl:url withParame:parame withMethod:VPKCRequestMethodPut withComplete:result];
}
/// PATCH
+ (VPKCRequestManager *)PATCH:(NSString *)url
withParame:(NSDictionary *)parame
withComplete:(void(^)(VPKCResponse *responseObj))result {
return [self requestConfigWithUrl:url withParame:parame withMethod:VPKCRequestMethodPatch withComplete:result];
}
/// DELETE
+ (VPKCRequestManager *)DELETE:(NSString *)url
withParame:(NSDictionary *)parame
withComplete:(void(^)(VPKCResponse *responseObj))result {
return [self requestConfigWithUrl:url withParame:parame withMethod:VPKCRequestMethodDelete withComplete:result];
}
/// 取消当前请求任务
- (void)cancelCurrentTask {
// cancel specific task
for (NSURLSessionDataTask* task in [_sessionManager tasks]) {
if (task.taskIdentifier == _taskIdentifier) {
[task cancel];
}
}
}
/// 取消所有请求任务
- (void)cancelAllTask {
[_sessionDataTask cancel];
}
+ (VPKCRequestManager *)sharedRequest {
static VPKCRequestManager *requestManage;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
requestManage = [[self alloc] initPrivate];
});
return requestManage;
}
- (instancetype)initPrivate {
if (self = [super init]) {
_reachable = YES;
_requestBaseUrl = [NSURL URLWithString:@"http://baidu.com"];
_requestMethod = VPKCRequestMethodGet;
_sessionManager = [AFHTTPSessionManager manager];
_sessionManager.requestSerializer = [AFJSONRequestSerializer serializer];
_sessionManager.responseSerializer = [AFJSONResponseSerializer serializer];
_sessionManager.requestSerializer.timeoutInterval = 30;
_sessionManager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html",@"application/json",@"text/plain", nil];
[_sessionManager setSecurityPolicy:[self customSecurityPolicy]];
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
[_sessionManager.reachabilityManager startMonitoring];
__weak typeof(self)weakSelf = self;
[_sessionManager.reachabilityManager setReachabilityStatusChangeBlock:^void(AFNetworkReachabilityStatus status)
{
weakSelf.reachable = [@(status) boolValue];
}];
}
return self;
}
//// 设置请求头
- (void)setHmacStringWithSessionManager:(AFHTTPRequestSerializer *)requestSerializer {
// NSString *time = [VPKCUtils timeToTurnTheTimestamp];
// NSString *hmac = [NSString stringWithFormat:@"%@\n%@/%@\n%@",time,kHmacUrl,_requestApiUrl,methodStirng[_requestMethod]];
// hmac = [NSString hmac:hmac];
// NSString *devID = [VPKCUserInfo sharedUserInfo].parentDeviceId;
// NSString *user = [VPKCUserInfo sharedUserInfo].username;
// NSString *child = [VPKCUserInfo sharedUserInfo].childDeviceId?:@"";
//
// [requestSerializer setValue:time forHTTPHeaderField:@"X-KC-TIME"];
// [requestSerializer setValue:hmac forHTTPHeaderField:@"X-KC-HMAC"];
// [requestSerializer setValue:devID forHTTPHeaderField:@"X-KC-DEVICEID"];
// [requestSerializer setValue:user forHTTPHeaderField:@"X-KC-USERNAME"];
// [requestSerializer setValue:child forHTTPHeaderField:@"X-KC-CHILD-DEVICEID"];
}
// https配置
- (AFSecurityPolicy*)customSecurityPolicy {
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"d" ofType:@"cer"];
NSData *certData = [NSData dataWithContentsOfFile:cerPath];
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
[securityPolicy setAllowInvalidCertificates:NO];
[securityPolicy setPinnedCertificates:@[certData]];
return securityPolicy;
}
//
/// 拼接url
- (NSString *)requestServiceUrlString {
if ([_requestApiUrl hasPrefix:@"http"]) {
return _requestApiUrl;
}
return [NSString stringWithFormat:@"%@/%@",_requestBaseUrl,_requestApiUrl];
}
#pragma mark ------------------------------------------------------------
- (void)requestStartWithWithSuccess:(void (^)(VPKCResponse *))result {
[self requestMethodWithSuccess:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(@"【request_responseObject】=%@ == %@",responseObject,task.response.URL.absoluteString);
VPKCResponse *response = [[VPKCResponse alloc] init];
response.responseObject = responseObject;
response.error = nil;
if ([task.response isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *r = (NSHTTPURLResponse *)task.response;
response.headerFields = r.allHeaderFields;
response.status = @(r.statusCode);
}
if (result) {
result(response);
}
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(@"【request_error】=%@ == Url = %@",error,task.response.URL.absoluteString);
VPKCResponse *response = [[VPKCResponse alloc] init];
response.error = error;
if ([task.response isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *r = (NSHTTPURLResponse *)task.response;
response.headerFields = r.allHeaderFields;
response.status = @(r.statusCode);
if ([response.status isEqualToNumber:@403]) {
NSData *data = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
if (data) {
NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *responseObject = [VPKCUtils jsonWithString:s];
NSLog(@"error = %@",responseObject);
response.content = responseObject[@"content"];
response.errorCode = responseObject[@"errorCode"];
response.errorDescription = responseObject[@"errorDescription"];
}
}
if ([response.status isEqualToNumber:@502]) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"连接服务器异常" message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:nil, nil];
[alertView show];
}
}
if (result) {
result(response);
}
}];
}
- (void)requestMethodWithSuccess:(void(^)(NSURLSessionDataTask *task, id responseObject))success failure:(void(^)(NSURLSessionDataTask * task, NSError * error))failure {
if (!_reachable) {
failure(nil,[NSError errorWithDomain:@"网络连接失败" code:-1 userInfo:nil]);
return ;
}
NSDictionary *parame = _requestParame;
NSString *URLString = [self requestServiceUrlString];
[self setHmacStringWithSessionManager:_sessionManager.requestSerializer];
NSLog(@"【URL】%@",URLString);
NSLog(@"【parame】%@",parame);
switch (_requestMethod)
{
case VPKCRequestMethodGet:
_sessionDataTask = [_sessionManager GET:URLString parameters:parame success:success failure:failure];
break;
case VPKCRequestMethodPost:
_sessionDataTask = [_sessionManager POST:URLString parameters:parame success:success failure:failure];
break;
case VPKCRequestMethodPut:
_sessionDataTask = [_sessionManager PUT:URLString parameters:parame success:success failure:failure];
break;
case VPKCRequestMethodDelete:
_sessionDataTask = [_sessionManager DELETE:URLString parameters:parame success:success failure:failure];
break;
case VPKCRequestMethodPatch:
_sessionDataTask = [_sessionManager PATCH:URLString parameters:parame success:success failure:failure];
break;
case VPKCRequestMethodHead:{
_sessionDataTask = [_sessionManager HEAD:URLString parameters:parame success:^(NSURLSessionDataTask * task) {
success(task,nil);
} failure:failure];
}
break;
default:
break;
}
_taskIdentifier = _sessionDataTask.taskIdentifier;
}
+ (VPKCRequestManager *)requestConfigWithUrl:(NSString *)url
withParame:(NSDictionary *)parame
withMethod:(VPKCRequestMethod)method
withComplete:(void(^)(VPKCResponse *responseObj))result
{
VPKCRequestManager *request = [VPKCRequestManager sharedRequest];
request.requestApiUrl = url;
request.requestParame = parame;
request.requestMethod = method;
[request requestStartWithWithSuccess:result];
return request;
}
@end
在VPKCUtils文件中 ——————/** 辅助工具类,根据需求进行添加 */
/**
* 将字符串转化为字典
*
* @param string JSON字符串
*
* @return 字典
*/
+ (NSDictionary *)jsonWithString:(NSString *)string;
+ (NSDictionary *)jsonWithString:(NSString *)string {
if (!string) {
return nil;
}
NSData *jsonData = [string dataUsingEncoding:NSUTF8StringEncoding];
NSError *err;
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&err];
if (err) {
return nil;
}
return dic;
}
iOS-在AFN基础上进行网络请求的封装的更多相关文章
- Angular网络请求的封装
很多时候,我很喜欢angular的编码风格,特别是angular支持typescript之后,完整的生命周期,完美的钩子函数,都是别的语言所无法替代的.这里我来说说我自己的网络请求封装,某种意义上来说 ...
- AFNetworking 2.5.x 网络请求的封装
AFNetworking 2.5.x 网络请求的封装 源码地址 https://github.com/YouXianMing/Networking 说明 1. 将block形式的请求转换成用代理来处理 ...
- IOS开发之—— 在AFN基础上进行的网络请求的封装
网络请求的思路:如果请求成功的话AFN的responseObject就是解析好的. 1发送网络请求:get/post/或者别的 带上URL,需要传的参数 2判断后台网络状态码有没有请求成功: 3 请求 ...
- Sagit.Framework For IOS 开发框架入门教程6:网络请求STHttp
前言: IOS的文章,今天,再来补一篇,Sagit的教程: 虽然感觉IOS的文章没什么观众,还是努力写吧,-_-〜 Sagit 开源地址:https://github.com/cyq1162/Sagi ...
- iOS:根据日志去定位网络请求发生的错误是由于服务端造成的,还是客户端造成的?
一.介绍 在项目开发中,服务端和客户端的协作尤为重要,而连接它们的最重要的环节之一就是网络请求,对于服务端而言,如果这个环节出现了错误,那么安全性就无从谈起,同时对于客户端而言,如果这个模块出现了错误 ...
- Swift3.0 Alamofire网络请求的封装(get,post,upload图片上传)转
转自: http://blog.csdn.net/C_calary/article/details/53193747 学习Swift 试着动手写个天气小app,搜集资料这个封装还蛮好用的. 我用的第三 ...
- iOS swift HandyJSON组合Alamofire发起网络请求并转换成模型
在swift开发中,发起网络请求大部分开发者应该都是使用Alamofire发起的网络请求,至于请求完成后JSON解析这一块有很多解决方案,我们今天这里使用HandyJSON来解析请求返回的数据并转化成 ...
- 关于ajax网络请求的封装
// 封装的ajax网络请求函数// obj 是一个对象function AJAX(obj){ //跨域请求 if (obj.dataType == "jsonp") ...
- Axios 网络请求组件封装 (鉴权、刷新、拦截)
一.前言 注意:本教程需要你对axios有一定的了解,不适用于小白(只能借鉴,希望你能自己动手),注释都写的很清楚.此封装并非完整版,已进行部分删减修改操作,但仍然适用于大部分业务场景,如果不适用于你 ...
随机推荐
- 通过字节码分析Java方法的静态分派与动态分派机制
在上一次[https://www.cnblogs.com/webor2006/p/9723289.html]中已经对Java方法的静态分派在字节码中的表现了,也就是方法重载其实是一种静态分派的体现,这 ...
- springboot中使用cache和redis
知识点:springboot中使用cache和redis (1)springboot中,整合了cache,我们只需要,在入口类上加 @EnableCaching 即可开启缓存 例如:在service层 ...
- Vue.js项目中使用 Ajax 和 FormDate 对象上传文件
let param = new FormData(); param.append("paths", this.ruleForm.uploadPath); param.append( ...
- Java核心技术 卷一 复习笔记(丁
面向对象1.面向对象设计概述 1.1.面向对象是什么 面向对象是一种程序设计范型(简称OOP),是针对对象进行开发,简化开发过程的一种设计方式 1.2.类 类是构造对象的模板,相当于一个烘焙模板,而对 ...
- pyinstaller打包程序包含openpyxl库问题解决
带有openpyxl库时,直接打包,总会失败: 原因:看本地文件...Anaconda3\Lib\site-packages\PyInstaller\hooks\hook-openpyxl.py 发现 ...
- BZOJ 4807 車 组合数学
思路:高精度\((what)\) 提交:2次(后来发现有种更快的写法) 题解: 设\(n>m\),那么显然答案为\(C(n,m)\),相当于只能放\(m\)个棋子,可以在\(n\)列中选任意不同 ...
- Catalan Number-卡特兰数入门
卡特兰数 首先,我们设f(n)=序列个数为n的出栈序列种数.同时,我们假定,从开始到栈第一次出到空为止,这段过程中第一个出栈的序数是k.特别地,如果栈直到整个过程结束时才空,则k=n. 令h(0)=1 ...
- 006_linux驱动之_ioremap函数使用
(一)学习linux驱动之初,对ioremap函数的个人理解 (二)博客:实验探究 ioremap 这篇文章作者通过验证来阐述自己的观点,个人觉得挺好的 (三)函数原型 基本简介 void * __i ...
- 彻底搞清楚setState
setState最常见的问题是,是异步的还是同步的? setState在React.Component中的函数,是同步函数.但是我们调用的时候,不同的传参和不同的调用位置都会导致不同的结果. 从页面看 ...
- sql 存储过程例子和学习demo
-------------------------------------------------------------------------- ------------------------- ...