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有一定的了解,不适用于小白(只能借鉴,希望你能自己动手),注释都写的很清楚.此封装并非完整版,已进行部分删减修改操作,但仍然适用于大部分业务场景,如果不适用于你 ...
随机推荐
- 传说中Python最难理解的点,看这完篇就够了
本文转载自简书,作者为菜鸟,感谢作者的辛苦付出. 这不是我第一次学Python入门课,去年.前年我都学过Python入门.所以文章的标题一点都没有标题党的意思.但是整个入门篇还有一个最难的东西没有讲, ...
- 0012SpringBoot访问首页
有三种方式可以实现访问首页: 第一种: 定义一个Controller,定义请求方法和返回内容,方法内容如下: @RequestMapping({"/","/index&q ...
- python中的数据类型(二)
一.列表(list) 列表是可变的,有序的(只要能索引的都是有序的) 列表的基本操作: 1.增 1.append 追加 例:lst.append(8) print (ls ...
- 02_已解决 [salt.minion :1758][ERROR ][52886] Returner mysql.returner could not be loaded: 'mysql' __virtual__ returned False: Could not import mysql returner; mysql python client is not installed.
总结:python2.7下的salt,要把 mysql-python也安装,并不是python3环境,看清,看清 Returners组件,master自动把值写入mysql数据库中,出现的问题 1.本 ...
- 010_STM32程序移植之_lib库建立
STM32之lib库建立 1. 测试环境:STM32C8T6 2. 测试接口: 3.串口使用串口一,波特率9600 单片机引脚------------CH340引脚 VCC-------------- ...
- mysql日期相减取小时
mysql日期相减取小时 TIMESTAMPDIFF(HOUR,a.StartTime,a.EndTime)
- 更改用户id 和组id
转自 http://blog.csdn.net/todd911/article/details/16370577 在unix系统中,特权是基于用户和组ID的,当程序需要增加特权,或需要访问当前并不允许 ...
- leveldb源码分析之Slice
转自:http://luodw.cc/2015/10/15/leveldb-02/ leveldb和redis这样的优秀开源框架都没有使用C++自带的字符串string,redis自己写了个sds,l ...
- 微信小程序之简单记账本开发记录(二)
1.打开开发者工具 2.从微信公众平台上获取到appid,或者使用测试号. 项目的大致目录如下: 一个小程序主体部分由三个文件组成,必须放在项目的根目录中 以app为开头的文件名用来布置作用于整个项目 ...
- 解析NaN
此文为自译文,且第一次翻译,有不足之处. 原英文地址:https://en.wikipedia.org/wiki/NaN 我的理解 32位下二进制的 NaN 存储格式为s111 1111 1111 1 ...