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基础上进行的网络请求的封装的更多相关文章
- iOS开发UI篇—Button基础
iOS开发UI篇—Button基础 一.简单说明 一般情况下,点击某个控件后,会做出相应反应的都是按钮 按钮的功能比较多,既能显示文字,又能显示图片,还能随时调整内部图片和文字的位置 二.按钮的三种状 ...
- Delphi for iOS开发指南(1):在Mac上配置你的开发环境
http://cache.baiducontent.com/c?m=9d78d513d99516f11ab7cf690d678c3b584380122ba7a0020fd18438e4732b4050 ...
- iOS开发系列—Objective-C之基础概览
概览 前面我们已经用了几章内容进行C语言介绍,当然要通过几篇文章完整的介绍C语言的知识是不太现实的,例如C语言的文件操作.内存申请等我们都没有重点介绍,当然核心知识点基本都已经提到了,后面有时间我们会 ...
- 李洪强iOS开发之【零基础学习iOS开发】【01-前言】02-准备
在上一讲中,介绍了什么是iOS开发.说简单一点,iOS开发,就是开发运行在iPhone或者iPad上的软件.这么一说完,应该有很多人就会产生一些疑惑,比如学习iOS开发是不是一定要买iPhone?需不 ...
- 李洪强iOS开发之【零基础学习iOS开发】【01-前言】01-开篇
从今天开始,我就开始更新[零基础学习iOS开发]这个专题.不管你是否涉足过IT领域,也不管你是理科生还是文科生,只要你对iOS开发感兴趣,都可以来阅读此专题.我尽量以通俗易懂的语言,让每个人都能够看懂 ...
- 李洪强iOS开发之【零基础学习iOS开发】【02-C语言】02-第一个C语言程序
前言 前面已经唠叨了这么多理论知识,从这讲开始,就要通过接触代码来学习C语言的语法.学习任何一门语言,首先要掌握的肯定是语法.学习C语言语法的目的:就是能够利用C语言编写程序,然后运行程序跟硬件(计算 ...
- 来自IOS开发工程师的零基础自学HTML5经验分享
移动互联网的火爆,而Html具有跨平台.开发快的优势,越来越受到开发者的青睐.感谢IOS开发工程师“小木___Boy”’带来的HTML5学习经验分享. 一.学习途径 1.很多视频网站 比如慕课.和极客 ...
- 李洪强iOS开发之【零基础学习iOS开发【01-前言】03-前景和难易度分析
一.iOS开发的前景 2012年3月份,苹果公司的市值已经突破5000亿美元,成为世界上市值最大的公司.5000亿是神马概念呢? 可以帮助陷入欧债危机的8个国家偿还债务 可以买下35个天安门广场.34 ...
- iOS 开发http post 文件的上传
iOS开发网络篇—文件的上传 说明:文件上传使用的时POST请求,通常把要上传的数据保存在请求体中.本文介绍如何不借助第三方框架实现iOS开发中得文件上传. 由于过程较为复杂,因此本文只贴出部分关键代 ...
随机推荐
- Recurrent Neural Network系列1--RNN(循环神经网络)概述
作者:zhbzz2007 出处:http://www.cnblogs.com/zhbzz2007 欢迎转载,也请保留这段声明.谢谢! 本文翻译自 RECURRENT NEURAL NETWORKS T ...
- CORS详解[译]
介绍 由于同源策略的缘故,以往我们跨域请求,会使用诸如JSON-P(不安全)或者代理(设置代理和维护繁琐)的方式.而跨源资源共享(Cross-Origin Resource Sharing)是一个W3 ...
- 谈谈一些有趣的CSS题目(三)-- 层叠顺序与堆栈上下文知多少
开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...
- ASP.NET Aries 入门开发教程2:配置出一个简单的列表页面
前言: 朋友们都期待我稳定地工作,但创业公司若要躺下,也非意念可控. 若人生注定了风雨飘摇,那就雨中前行了. 最机开始看聊新的工作机会,欢迎推荐,创业公司也可! 同时,趁着自由时间,抓紧把这系列教程给 ...
- setAttribute()
●节点分为不同的类型:元素节点.属性节点和文本节点等. ●getElementById()方法将返回一个对象,该对象对应着文档里的一个特定的元素节点. ●getElementsByTagNam ...
- ABP文档 - SignalR 集成
文档目录 本节内容: 简介 安装 服务端 客户端 连接确立 内置功能 通知 在线客户端 帕斯卡 vs 骆峰式 你的SignalR代码 简介 使用Abp.Web.SignalR nuget包,使基于应用 ...
- 问题记录:EntityFramework 一对一关系映射
EntityFramework 一对一关系映射有很多种,比如主键作为关联,配置比较简单,示例代码: public class Teacher { public int Id { get; set; } ...
- JAVA程序员常用软件整理下载
********为了大家学习方便,特意整理软件下载如下:*************Java类软件:-------------------------------JDK7.0:http://pan.ba ...
- Android 算法 关于递归和二分法的小算法
// 1. 实现一个函数,在一个有序整型数组中二分查找出指定的值,找到则返回该值的位置,找不到返回 -1. package demo; public class Mytest { public st ...
- 如何通过Git GUI将自己本地的项目上传至Github
最近在学习node.js和react,顺便复习了下AngluarJS相关的东西,写了些小demo想放在GitHub上,之前仅限于只申请了GitHub账号从没用过,今天花半天时间查资料认真学习Githu ...