.h里面
//
// CJNetworkRequest.m
//
//
// Created by YouChangJiang on 16/4/19.
// Copyright © 2016年 YouChangJiang. All rights reserved.
//
/*
* CJNetworkApi的一些功能和说明:
1. 使用CJNetworkRequest做一些GET、POST、PUT、DELETE请求,与业务逻辑对接部分直接以数组或者字典的形式返回。
2. 网络下载、上传文件,以block的形式返回实时的下载、上传进度,上传文件参数通过模型CJFileConfig去存取。
3. 通过继承于CJDataService来将一些数据处理,模型转化封装起来,于业务逻辑对接返回的是对应的模型,减少Controllor处理数据处理逻辑的压力。
4. 自定义一些回调的block
*/
#import "CJNetworkRequest.h"
static BOOL isNetworkUse;
static NSMutableDictionary *dictionaryForConnectionTag;
@implementation CJNetworkRequest
+(void)initialize {
dictionaryForConnectionTag = [[NSMutableDictionary alloc]initWithCapacity:20];
}
+(NSString *) paramAES128String:(NSDictionary *) param {
NSMutableDictionary *muParam = [NSMutableDictionary dictionaryWithDictionary:param];
[muParam setObject:[NSString stringWithFormat:@"%ld",(long)[[NSDate date] timeIntervalSince1970]] forKey:@"requesttime"];
NSDictionary *localDic =[[NSBundle mainBundle] infoDictionary];
NSString *currentVersion = [localDic objectForKey:@"CFBundleShortVersionString"];
[muParam setObject:currentVersion forKey:@"version"];
NSString *jsonString = nil;
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:muParam
options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
error:&error];
if (!jsonData) {
NSLog(@"Got an error: %@", error);
} else {
jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
return jsonString;
}
+ (void)getRequest:(NSString *)url params:(NSDictionary *)params isEncryption:(BOOL) flag success:(requestSuccessBlock)successHandler failure:(requestFailureBlock)failureHandler {
NSString *absoluteURL = [self generateGETAbsoluteURL:url params:params];
NSString *key = [MyShareClass ycjnetworking_md5:absoluteURL];
NSLog(@"%@",key);
if (![self verifyReuqest:key]) {
return;
}
AFHTTPSessionManager *manager = [self getRequstManager];
NSDictionary *paramAESDic = flag?@{@"guess":[DES3Util AES128Encrypt:[self paramAES128String:params]]}:params;
[manager GET:url parameters:paramAESDic progress:^(NSProgress * _Nonnull downloadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
[dictionaryForConnectionTag removeObjectForKey:key];
successHandler(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
CJLog(@"------请求失败-------%@",error);
[((JMBaseVC *)[MyShareClass getInstance].mainViewController) hideLoading];
if (error.code == -1009) {
[Dialog toastCenter:error.localizedDescription];
} else {
[[Dialog Instance] hideProgress];
}
[dictionaryForConnectionTag removeObjectForKey:key];
failureHandler(error);
}];
}
+ (void)postRequest:(NSString *)url params:(NSDictionary *)params isEncryption:(BOOL) flag success:(requestSuccessBlock)successHandler failure:(requestFailureBlock)failureHandler {
NSString *absoluteURL = [self generateGETAbsoluteURL:url params:params];
NSString *key = [MyShareClass ycjnetworking_md5:absoluteURL];
if (![self verifyReuqest:key]) {
return;
}
AFHTTPSessionManager *manager = [self getRequstManager];
NSDictionary *paramAESDic = flag?@{@"guess":[DES3Util AES128Encrypt:[self paramAES128String:params]]}:params;
[manager POST:url parameters:paramAESDic progress:^(NSProgress * _Nonnull downloadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
[dictionaryForConnectionTag removeObjectForKey:key];
successHandler(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
CJLog(@"------请求失败-------%@",error);
[((JMBaseVC *)[MyShareClass getInstance].mainViewController) hideLoading];
if (error.code == -1009) {
[Dialog toastCenter:error.localizedDescription];
} else {
[[Dialog Instance] hideProgress];
}
[dictionaryForConnectionTag removeObjectForKey:key];
failureHandler(error);
}];
}
+ (void)putRequest:(NSString *)url params:(NSDictionary *)params success:(requestSuccessBlock)successHandler failure:(requestFailureBlock)failureHandler {
AFHTTPSessionManager *manager = [self getRequstManager];
[manager PUT:url parameters:params success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
successHandler(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
CJLog(@"------请求失败-------%@",error);
failureHandler(error);
}];
}
+ (void)deleteRequest:(NSString *)url params:(NSDictionary *)params success:(requestSuccessBlock)successHandler failure:(requestFailureBlock)failureHandler {
AFHTTPSessionManager *manager = [self getRequstManager];
[manager DELETE:url parameters:params success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
successHandler(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
CJLog(@"------请求失败-------%@",error);
if (error.code == -1009) {
[Dialog toastCenter:error.localizedDescription];
[((JMBaseVC *)[MyShareClass getInstance].mainViewController).refreshTB.mj_header endRefreshing];
}
failureHandler(error);
}];
}
/**
下载文件,监听下载进度
*/
+ (void)downloadRequest:(NSString *)url successAndProgress:(progressBlock)progressHandler complete:(responseBlock)completionHandler {
if (![self checkNetworkStatus]) {
progressHandler(0, 0, 0);
completionHandler(nil, nil);
return;
}
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:sessionConfiguration];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
NSURL *documentUrl = [[NSFileManager defaultManager] URLForDirectory :NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
return [documentUrl URLByAppendingPathComponent:[response suggestedFilename]];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nonnull filePath, NSError * _Nonnull error) {
if (error) {
CJLog(@"------下载失败-------%@",error);
}
completionHandler(response, error);
}];
[manager setDownloadTaskDidWriteDataBlock:^(NSURLSession * _Nonnull session, NSURLSessionDownloadTask * _Nonnull downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) {
progressHandler(bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
}];
[downloadTask resume];
}
/**
* 发送一个POST请求
* @param fileConfig 文件相关参数模型
* @param success 请求成功后的回调
* @param failure 请求失败后的回调
* 无上传进度监听
*/
+ (void)updateRequest:(NSString *)url params:(NSDictionary *)params fileConfig:(CJFileConfig *)fileConfig success:(requestSuccessBlock)successHandler failure:(requestFailureBlock)failureHandler {
AFHTTPSessionManager *manager = [self getRequstManager];
[manager POST:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
[formData appendPartWithFileData:fileConfig.fileData name:fileConfig.name fileName:fileConfig.fileName mimeType:fileConfig.mimeType];
} progress:^(NSProgress * _Nonnull downloadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
successHandler(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
CJLog(@"------上传失败-------%@",error);
failureHandler(error);
}];
}
/**
上传文件,监听上传进度
*/
+ (void)updateRequest:(NSString *)url params:(NSDictionary *)params fileConfig:(CJFileConfig *)fileConfig successAndProgress:(progressBlock)progressHandler complete:(responseBlock)completionHandler {
//获取上传进度
AFHTTPSessionManager *manager = [self getRequstManager];
NSURLSessionDataTask *session = [manager POST:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
// 上传图片,以文件流的格式
[formData appendPartWithFileData:fileConfig.fileData name:fileConfig.name fileName:fileConfig.fileName mimeType:fileConfig.mimeType];
} progress:^(NSProgress * _Nonnull uploadProgress) {
progressHandler(uploadProgress.completedUnitCount, uploadProgress.totalUnitCount, uploadProgress.totalUnitCount - uploadProgress.completedUnitCount);
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
completionHandler(responseObject, nil);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
completionHandler(nil, error);
if (error) {
CJLog(@"------上传失败-------%@",error);
}
}];
[session resume];
}
+ (AFHTTPSessionManager *)getRequstManager {
// 开启转圈圈
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
AFHTTPSessionManager *manager = nil;
manager = [AFHTTPSessionManager manager];
manager.responseSerializer.acceptableContentTypes = nil;//[NSSet setWithObject:@"text/ plain"];
manager.securityPolicy = [AFSecurityPolicy defaultPolicy];
manager.securityPolicy.allowInvalidCertificates = YES;// https manager.securityPolicy.validatesDomainName = NO;//
manager.requestSerializer.stringEncoding = NSUTF8StringEncoding;
manager.responseSerializer.acceptableContentTypes = [NSSet setWithArray:@[@"application/json",
@"text/html",
@"text/json",
@"text/plain",
@"text/javascript",
@"text/xml",
@"image/*"]];
// 设置允许同时最大并发数量,过大容易出问题
manager.operationQueue.maxConcurrentOperationCount = 3;
manager.requestSerializer.timeoutInterval = 30;
return manager;
}
#pragma mark-Private
/**
url编码
*/
+ (NSString *)encodeUrl:(NSString *)url {
return [self cj_URLEncode:url];
}
+ (NSString *)cj_URLEncode:(NSString *)url {
NSString *newString =
CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(CFStringRef)url,
NULL,
CFSTR(":/?#[]@!$ &'()*+,;=\"<>%{}|\\^~`"), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding)));
if (newString) {
return newString;
}
return url;
}
/**
监控网络状态
*/
+ (BOOL)checkNetworkStatus {
AFNetworkReachabilityManager *reachabilityManager = [AFNetworkReachabilityManager sharedManager];
[reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
if (status == AFNetworkReachabilityStatusUnknown) {
isNetworkUse = YES;
} else if (status == AFNetworkReachabilityStatusReachableViaWiFi){
isNetworkUse = YES;
} else if (status == AFNetworkReachabilityStatusReachableViaWWAN){
isNetworkUse = YES;
} else if (status == AFNetworkReachabilityStatusNotReachable){
// 网络异常操作
isNetworkUse = NO;
CJLog(@"网络异常,请检查网络是否可用!");
}
}];
[reachabilityManager startMonitoring];
return isNetworkUse;
}
// 仅对一级字典结构起作用
+ (NSString *)generateGETAbsoluteURL:(NSString *)url params:(id)params {
if (params == nil || ![params isKindOfClass:[NSDictionary class]] || [params count] == 0) {
return url;
}
NSString *queries = @"";
for (NSString *key in params) {
id value = [params objectForKey:key];
if ([value isKindOfClass:[NSDictionary class]]) {
continue;
} else if ([value isKindOfClass:[NSArray class]]) {
continue;
} else if ([value isKindOfClass:[NSSet class]]) {
continue;
} else {
queries = [NSString stringWithFormat:@"%@%@=%@&",
(queries.length == 0 ? @"&" : queries),
key,
value];
}
}
if (queries.length > 1) {
queries = [queries substringToIndex:queries.length - 1];
}
if (([url hasPrefix:@"http://"] || [url hasPrefix:@"https://"]) && queries.length > 1) {
if ([url rangeOfString:@"?"].location != NSNotFound
|| [url rangeOfString:@"#"].location != NSNotFound) {
url = [NSString stringWithFormat:@"%@%@", url, queries];
} else {
queries = [queries substringFromIndex:1];
url = [NSString stringWithFormat:@"%@?%@", url, queries];
}
}
return url.length == 0 ? queries : url;
}
/**
* 该方法用于判断进入的网络连接请求是否是第一次,或者是否是重复请求(上一次请求还没结束,相同的请求又开始了)
*
* @param verifyDictionary 外部传来的参数
*
* @return 是否同意发起请求
*/
+(BOOL)verifyReuqest:(NSString*)verifyString{
/**
* 第一次请求经过数据中心类时,做一下标记,然后将请求交给AFHTTPRequestOperation。然后有返回数据,则将该标记清空。这样,在该过程中,如果有重复请求,在存在tag标记时,不会将请求交给AFHTTPRequestOperation
*/
/**
* 这个标识存在于传来的NSDictionary中,这样就可以确保每个类中每个请求传来的标识都不一样。
使用NSMutableDictionary 储存该标识。key - value 对应 ‘key’储存的是每个请求的标识,‘value’储存的是请求的状态。默认是NO,发起请求时改变为YES,收到返回数据的时候还原为NO。如果有重复请求进入,则判断value为YES,阻止该次请求。
*/
if ([dictionaryForConnectionTag objectForKey:verifyString]) {
/**
* 如果NSMutableDictionary中存在该标识,则去查看对应value的状态
*/
if ([[dictionaryForConnectionTag objectForKey:verifyString] integerValue]== NO) {
return NO;
} else {
return YES;
}
} else{
/**
* 如果没有该标识,则说明该请求是第一次,将其加入字典中,然后发起请求,百度统计
*/
[dictionaryForConnectionTag setObject:[NSNumber numberWithBool:0] forKey:verifyString];
return YES;
}
}
@end
/**
* 用来封装上传参数
*/
@implementation CJFileConfig
+ (instancetype)fileConfigWithfileData:(NSData *)fileData name:(NSString *)name fileName:(NSString *)fileName mimeType:(NSString *)mimeType {
return [[self alloc] initWithfileData:fileData name:name fileName:fileName mimeType:mimeType];
}
- (instancetype)initWithfileData:(NSData *)fileData name:(NSString *)name fileName:(NSString *)fileName mimeType:(NSString *)mimeType {
if (self = [super init]) {
_fileData = fileData;
_name = name;
_fileName = fileName;
_mimeType = mimeType;
}
return self;
}
@end
.m里面
//
// CJNetworkRequest.m
//
//
// Created by YouChangJiang on 16/4/19.
// Copyright © 2016年 YouChangJiang. All rights reserved.
//
/*
* CJNetworkApi的一些功能和说明:
1. 使用CJNetworkRequest做一些GET、POST、PUT、DELETE请求,与业务逻辑对接部分直接以数组或者字典的形式返回。
2. 网络下载、上传文件,以block的形式返回实时的下载、上传进度,上传文件参数通过模型CJFileConfig去存取。
3. 通过继承于CJDataService来将一些数据处理,模型转化封装起来,于业务逻辑对接返回的是对应的模型,减少Controllor处理数据处理逻辑的压力。
4. 自定义一些回调的block
*/
#import "CJNetworkRequest.h"
static BOOL isNetworkUse;
static NSMutableDictionary *dictionaryForConnectionTag;
@implementation CJNetworkRequest
+(void)initialize {
dictionaryForConnectionTag = [[NSMutableDictionary alloc]initWithCapacity:20];
}
+(NSString *) paramAES128String:(NSDictionary *) param {
NSMutableDictionary *muParam = [NSMutableDictionary dictionaryWithDictionary:param];
[muParam setObject:[NSString stringWithFormat:@"%ld",(long)[[NSDate date] timeIntervalSince1970]] forKey:@"requesttime"];
NSDictionary *localDic =[[NSBundle mainBundle] infoDictionary];
NSString *currentVersion = [localDic objectForKey:@"CFBundleShortVersionString"];
[muParam setObject:currentVersion forKey:@"version"];
NSString *jsonString = nil;
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:muParam
options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
error:&error];
if (!jsonData) {
NSLog(@"Got an error: %@", error);
} else {
jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
return jsonString;
}
+ (void)getRequest:(NSString *)url params:(NSDictionary *)params isEncryption:(BOOL) flag success:(requestSuccessBlock)successHandler failure:(requestFailureBlock)failureHandler {
NSString *absoluteURL = [self generateGETAbsoluteURL:url params:params];
NSString *key = [MyShareClass ycjnetworking_md5:absoluteURL];
NSLog(@"%@",key);
if (![self verifyReuqest:key]) {
return;
}
AFHTTPSessionManager *manager = [self getRequstManager];
NSDictionary *paramAESDic = flag?@{@"guess":[DES3Util AES128Encrypt:[self paramAES128String:params]]}:params;
[manager GET:url parameters:paramAESDic progress:^(NSProgress * _Nonnull downloadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
[dictionaryForConnectionTag removeObjectForKey:key];
successHandler(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
CJLog(@"------请求失败-------%@",error);
[((JMBaseVC *)[MyShareClass getInstance].mainViewController) hideLoading];
if (error.code == -1009) {
[Dialog toastCenter:error.localizedDescription];
} else {
[[Dialog Instance] hideProgress];
}
[dictionaryForConnectionTag removeObjectForKey:key];
failureHandler(error);
}];
}
+ (void)postRequest:(NSString *)url params:(NSDictionary *)params isEncryption:(BOOL) flag success:(requestSuccessBlock)successHandler failure:(requestFailureBlock)failureHandler {
NSString *absoluteURL = [self generateGETAbsoluteURL:url params:params];
NSString *key = [MyShareClass ycjnetworking_md5:absoluteURL];
if (![self verifyReuqest:key]) {
return;
}
AFHTTPSessionManager *manager = [self getRequstManager];
NSDictionary *paramAESDic = flag?@{@"guess":[DES3Util AES128Encrypt:[self paramAES128String:params]]}:params;
[manager POST:url parameters:paramAESDic progress:^(NSProgress * _Nonnull downloadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
[dictionaryForConnectionTag removeObjectForKey:key];
successHandler(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
CJLog(@"------请求失败-------%@",error);
[((JMBaseVC *)[MyShareClass getInstance].mainViewController) hideLoading];
if (error.code == -1009) {
[Dialog toastCenter:error.localizedDescription];
} else {
[[Dialog Instance] hideProgress];
}
[dictionaryForConnectionTag removeObjectForKey:key];
failureHandler(error);
}];
}
+ (void)putRequest:(NSString *)url params:(NSDictionary *)params success:(requestSuccessBlock)successHandler failure:(requestFailureBlock)failureHandler {
AFHTTPSessionManager *manager = [self getRequstManager];
[manager PUT:url parameters:params success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
successHandler(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
CJLog(@"------请求失败-------%@",error);
failureHandler(error);
}];
}
+ (void)deleteRequest:(NSString *)url params:(NSDictionary *)params success:(requestSuccessBlock)successHandler failure:(requestFailureBlock)failureHandler {
AFHTTPSessionManager *manager = [self getRequstManager];
[manager DELETE:url parameters:params success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
successHandler(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
CJLog(@"------请求失败-------%@",error);
if (error.code == -1009) {
[Dialog toastCenter:error.localizedDescription];
[((JMBaseVC *)[MyShareClass getInstance].mainViewController).refreshTB.mj_header endRefreshing];
}
failureHandler(error);
}];
}
/**
下载文件,监听下载进度
*/
+ (void)downloadRequest:(NSString *)url successAndProgress:(progressBlock)progressHandler complete:(responseBlock)completionHandler {
if (![self checkNetworkStatus]) {
progressHandler(0, 0, 0);
completionHandler(nil, nil);
return;
}
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:sessionConfiguration];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
NSURL *documentUrl = [[NSFileManager defaultManager] URLForDirectory :NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
return [documentUrl URLByAppendingPathComponent:[response suggestedFilename]];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nonnull filePath, NSError * _Nonnull error) {
if (error) {
CJLog(@"------下载失败-------%@",error);
}
completionHandler(response, error);
}];
[manager setDownloadTaskDidWriteDataBlock:^(NSURLSession * _Nonnull session, NSURLSessionDownloadTask * _Nonnull downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) {
progressHandler(bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
}];
[downloadTask resume];
}
/**
* 发送一个POST请求
* @param fileConfig 文件相关参数模型
* @param success 请求成功后的回调
* @param failure 请求失败后的回调
* 无上传进度监听
*/
+ (void)updateRequest:(NSString *)url params:(NSDictionary *)params fileConfig:(CJFileConfig *)fileConfig success:(requestSuccessBlock)successHandler failure:(requestFailureBlock)failureHandler {
AFHTTPSessionManager *manager = [self getRequstManager];
[manager POST:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
[formData appendPartWithFileData:fileConfig.fileData name:fileConfig.name fileName:fileConfig.fileName mimeType:fileConfig.mimeType];
} progress:^(NSProgress * _Nonnull downloadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
successHandler(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
CJLog(@"------上传失败-------%@",error);
failureHandler(error);
}];
}
/**
上传文件,监听上传进度
*/
+ (void)updateRequest:(NSString *)url params:(NSDictionary *)params fileConfig:(CJFileConfig *)fileConfig successAndProgress:(progressBlock)progressHandler complete:(responseBlock)completionHandler {
//获取上传进度
AFHTTPSessionManager *manager = [self getRequstManager];
NSURLSessionDataTask *session = [manager POST:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
// 上传图片,以文件流的格式
[formData appendPartWithFileData:fileConfig.fileData name:fileConfig.name fileName:fileConfig.fileName mimeType:fileConfig.mimeType];
} progress:^(NSProgress * _Nonnull uploadProgress) {
progressHandler(uploadProgress.completedUnitCount, uploadProgress.totalUnitCount, uploadProgress.totalUnitCount - uploadProgress.completedUnitCount);
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
completionHandler(responseObject, nil);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
completionHandler(nil, error);
if (error) {
CJLog(@"------上传失败-------%@",error);
}
}];
[session resume];
}
+ (AFHTTPSessionManager *)getRequstManager {
// 开启转圈圈
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
AFHTTPSessionManager *manager = nil;
manager = [AFHTTPSessionManager manager];
manager.responseSerializer.acceptableContentTypes = nil;//[NSSet setWithObject:@"text/ plain"];
manager.securityPolicy = [AFSecurityPolicy defaultPolicy];
manager.securityPolicy.allowInvalidCertificates = YES;// https manager.securityPolicy.validatesDomainName = NO;//
manager.requestSerializer.stringEncoding = NSUTF8StringEncoding;
manager.responseSerializer.acceptableContentTypes = [NSSet setWithArray:@[@"application/json",
@"text/html",
@"text/json",
@"text/plain",
@"text/javascript",
@"text/xml",
@"image/*"]];
// 设置允许同时最大并发数量,过大容易出问题
manager.operationQueue.maxConcurrentOperationCount = 3;
manager.requestSerializer.timeoutInterval = 30;
return manager;
}
#pragma mark-Private
/**
url编码
*/
+ (NSString *)encodeUrl:(NSString *)url {
return [self cj_URLEncode:url];
}
+ (NSString *)cj_URLEncode:(NSString *)url {
NSString *newString =
CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(CFStringRef)url,
NULL,
CFSTR(":/?#[]@!$ &'()*+,;=\"<>%{}|\\^~`"), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding)));
if (newString) {
return newString;
}
return url;
}
/**
监控网络状态
*/
+ (BOOL)checkNetworkStatus {
AFNetworkReachabilityManager *reachabilityManager = [AFNetworkReachabilityManager sharedManager];
[reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
if (status == AFNetworkReachabilityStatusUnknown) {
isNetworkUse = YES;
} else if (status == AFNetworkReachabilityStatusReachableViaWiFi){
isNetworkUse = YES;
} else if (status == AFNetworkReachabilityStatusReachableViaWWAN){
isNetworkUse = YES;
} else if (status == AFNetworkReachabilityStatusNotReachable){
// 网络异常操作
isNetworkUse = NO;
CJLog(@"网络异常,请检查网络是否可用!");
}
}];
[reachabilityManager startMonitoring];
return isNetworkUse;
}
// 仅对一级字典结构起作用
+ (NSString *)generateGETAbsoluteURL:(NSString *)url params:(id)params {
if (params == nil || ![params isKindOfClass:[NSDictionary class]] || [params count] == 0) {
return url;
}
NSString *queries = @"";
for (NSString *key in params) {
id value = [params objectForKey:key];
if ([value isKindOfClass:[NSDictionary class]]) {
continue;
} else if ([value isKindOfClass:[NSArray class]]) {
continue;
} else if ([value isKindOfClass:[NSSet class]]) {
continue;
} else {
queries = [NSString stringWithFormat:@"%@%@=%@&",
(queries.length == 0 ? @"&" : queries),
key,
value];
}
}
if (queries.length > 1) {
queries = [queries substringToIndex:queries.length - 1];
}
if (([url hasPrefix:@"http://"] || [url hasPrefix:@"https://"]) && queries.length > 1) {
if ([url rangeOfString:@"?"].location != NSNotFound
|| [url rangeOfString:@"#"].location != NSNotFound) {
url = [NSString stringWithFormat:@"%@%@", url, queries];
} else {
queries = [queries substringFromIndex:1];
url = [NSString stringWithFormat:@"%@?%@", url, queries];
}
}
return url.length == 0 ? queries : url;
}
/**
* 该方法用于判断进入的网络连接请求是否是第一次,或者是否是重复请求(上一次请求还没结束,相同的请求又开始了)
*
* @param verifyDictionary 外部传来的参数
*
* @return 是否同意发起请求
*/
+(BOOL)verifyReuqest:(NSString*)verifyString{
/**
* 第一次请求经过数据中心类时,做一下标记,然后将请求交给AFHTTPRequestOperation。然后有返回数据,则将该标记清空。这样,在该过程中,如果有重复请求,在存在tag标记时,不会将请求交给AFHTTPRequestOperation
*/
/**
* 这个标识存在于传来的NSDictionary中,这样就可以确保每个类中每个请求传来的标识都不一样。
使用NSMutableDictionary 储存该标识。key - value 对应 ‘key’储存的是每个请求的标识,‘value’储存的是请求的状态。默认是NO,发起请求时改变为YES,收到返回数据的时候还原为NO。如果有重复请求进入,则判断value为YES,阻止该次请求。
*/
if ([dictionaryForConnectionTag objectForKey:verifyString]) {
/**
* 如果NSMutableDictionary中存在该标识,则去查看对应value的状态
*/
if ([[dictionaryForConnectionTag objectForKey:verifyString] integerValue]== NO) {
return NO;
} else {
return YES;
}
} else{
/**
* 如果没有该标识,则说明该请求是第一次,将其加入字典中,然后发起请求,百度统计
*/
[dictionaryForConnectionTag setObject:[NSNumber numberWithBool:0] forKey:verifyString];
return YES;
}
}
@end
/**
* 用来封装上传参数
*/
@implementation CJFileConfig
+ (instancetype)fileConfigWithfileData:(NSData *)fileData name:(NSString *)name fileName:(NSString *)fileName mimeType:(NSString *)mimeType {
return [[self alloc] initWithfileData:fileData name:name fileName:fileName mimeType:mimeType];
}
- (instancetype)initWithfileData:(NSData *)fileData name:(NSString *)name fileName:(NSString *)fileName mimeType:(NSString *)mimeType {
if (self = [super init]) {
_fileData = fileData;
_name = name;
_fileName = fileName;
_mimeType = mimeType;
}
return self;
}
@end