Files
mier_ios/SweetParty/Expand/NetWork/MLNetWorkHelper.m
2025-08-11 10:43:19 +08:00

530 lines
22 KiB
Objective-C
Executable File
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// MLNetWorkHelper.m
// HuiBao
//
// Created by 玛丽 on 2017/11/22.
// Copyright © 2017年 玛丽. All rights reserved.
//
#import "MLNetWorkHelper.h"
#import "Global.h"
@implementation MLNetWorkHelper
static BOOL _isOpenLog; // 是否已开启日志打印
static NSMutableArray *_allSessionTask;
static AFHTTPSessionManager *_sessionManager;
#pragma mark - 开始监听网络
+ (void)networkStatusWithBlock:(MLNetworkStatus)networkStatus {
[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
switch (status) {
case AFNetworkReachabilityStatusUnknown:
networkStatus ? networkStatus(MLNetworkStatusUnknown) : nil;
if (_isOpenLog) MYLog(@"未知网络");
break;
case AFNetworkReachabilityStatusNotReachable:
networkStatus ? networkStatus(MLNetworkStatusNotReachable) : nil;
if (_isOpenLog) MYLog(@"无网络");
break;
case AFNetworkReachabilityStatusReachableViaWWAN:
networkStatus ? networkStatus(MLNetworkStatusReachableViaWWAN) : nil;
if (_isOpenLog) MYLog(@"手机自带网络");
break;
case AFNetworkReachabilityStatusReachableViaWiFi:
networkStatus ? networkStatus(MLNetworkStatusReachableViaWiFi) : nil;
if (_isOpenLog) MYLog(@"WIFI");
break;
}
}];
}
+ (BOOL)isNetwork {
return [AFNetworkReachabilityManager sharedManager].reachable;
}
+ (BOOL)isWWANNetwork {
return [AFNetworkReachabilityManager sharedManager].reachableViaWWAN;
}
+ (BOOL)isWiFiNetwork {
return [AFNetworkReachabilityManager sharedManager].reachableViaWiFi;
}
+ (void)openLog {
_isOpenLog = YES;
}
+ (void)closeLog {
_isOpenLog = NO;
}
+ (void)cancelAllRequest {
// 锁操作
@synchronized(self) {
[[self allSessionTask] enumerateObjectsUsingBlock:^(NSURLSessionTask *_Nonnull task, NSUInteger idx, BOOL * _Nonnull stop) {
[task cancel];
}];
[[self allSessionTask] removeAllObjects];
}
}
+ (void)cancelRequestWithURL:(NSString *)URL {
if (!URL) { return; }
@synchronized (self) {
[[self allSessionTask] enumerateObjectsUsingBlock:^(NSURLSessionTask *_Nonnull task, NSUInteger idx, BOOL * _Nonnull stop) {
if ([task.currentRequest.URL.absoluteString hasPrefix:URL]) {
[task cancel];
[[self allSessionTask] removeObject:task];
*stop = YES;
}
}];
}
}
#pragma mark - GET请求无缓存
+ (NSURLSessionTask *)GET:(NSString *)URL
parameters:(id)parameters
success:(MLHttpRequestSuccess)success
failure:(MLHttpRequestFailed)failure {
return [self GET:URL parameters:parameters responseCache:nil success:success failure:failure];
}
#pragma mark - POST请求无缓存
+ (NSURLSessionTask *)POST:(NSString *)URL
parameters:(id)parameters
success:(MLHttpRequestSuccess)success
failure:(MLHttpRequestFailed)failure {
return [self POST:URL parameters:parameters responseCache:nil success:success failure:failure];
}
#pragma mark - GET请求自动缓存
+ (NSURLSessionTask *)GET:(NSString *)URL
parameters:(id)parameters
responseCache:(MLHttpRequestCache)responseCache
success:(MLHttpRequestSuccess)success
failure:(MLHttpRequestFailed)failure {
//读取缓存
responseCache!=nil ? responseCache([MLNetworkCache httpCacheForURL:URL parameters:parameters]) : nil;
// //http://zkw.org.cn/api/Login/getCode
// if ([URL isEqualToString:@"http://zkw.org.cn/api/Login/getCode"]) {
// _sessionManager.requestSerializer = [AFHTTPRequestSerializer serializer];
// _sessionManager.responseSerializer = [AFHTTPResponseSerializer serializer];
// }else{
// _sessionManager.requestSerializer = [AFJSONRequestSerializer serializer];
// _sessionManager.responseSerializer = [AFJSONResponseSerializer serializer];
// }
NSURLSessionTask *sessionTask = [_sessionManager GET:URL parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (_isOpenLog) {
// if ([URL isEqualToString:@"http://zkw.org.cn/api/Login/getCode"]) {
// LJLog(@"responseObject = %@",[NSString stringWithFormat:@"%@",responseObject]);
// }else{
// LJLog(@"responseObject = %@",responseObject);
// }
MYLog(@"responseObject = %@",responseObject);
}
[[self allSessionTask] removeObject:task];
success ? success(responseObject) : nil;
//对数据进行异步缓存
responseCache!=nil ? [MLNetworkCache setHttpCache:responseObject URL:URL parameters:parameters] : nil;
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (_isOpenLog) {MYLog(@"error = %@",error);}
[[self allSessionTask] removeObject:task];
failure ? failure(error) : nil;
}];
// 添加sessionTask到数组
sessionTask ? [[self allSessionTask] addObject:sessionTask] : nil ;
return sessionTask;
}
#pragma mark - POST请求自动缓存
+ (NSURLSessionTask *)POST:(NSString *)URL
parameters:(id)parameters
responseCache:(MLHttpRequestCache)responseCache
success:(MLHttpRequestSuccess)success
failure:(MLHttpRequestFailed)failure {
//读取缓存
responseCache!=nil ? responseCache([MLNetworkCache httpCacheForURL:URL parameters:parameters]) : nil;
NSURLSessionTask *sessionTask = [_sessionManager POST:URL parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (_isOpenLog) {
MYLog(@"responseObject = %@",responseObject);}
[[self allSessionTask] removeObject:task];
success ? success(responseObject) : nil;
//对数据进行异步缓存
responseCache!=nil ? [MLNetworkCache setHttpCache:responseObject URL:URL parameters:parameters] : nil;
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (_isOpenLog) {MYLog(@"error = %@",error);}
[[self allSessionTask] removeObject:task];
failure ? failure(error) : nil;
}];
// 添加最新的sessionTask到数组
sessionTask ? [[self allSessionTask] addObject:sessionTask] : nil ;
return sessionTask;
}
#pragma mark - 上传文件
+ (NSURLSessionTask *)uploadFileWithURL:(NSString *)URL
parameters:(id)parameters
name:(NSString *)name
filePath:(NSString *)filePath
progress:(MLHttpProgress)progress
success:(MLHttpRequestSuccess)success
failure:(MLHttpRequestFailed)failure {
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy defaultPolicy];
// 客户端是否信任非法证书
// securityPolicy.allowInvalidCertificates = YES;
// 是否在证书域字段中验证域名
// securityPolicy.validatesDomainName = NO;
// _sessionManager.securityPolicy = securityPolicy;
NSURLSessionTask *sessionTask = [_sessionManager POST:URL parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
NSError *error = nil;
[formData appendPartWithFileURL:[NSURL URLWithString:filePath] name:name error:&error];
(failure && error) ? failure(error) : nil;
} progress:^(NSProgress * _Nonnull uploadProgress) {
//上传进度
dispatch_sync(dispatch_get_main_queue(), ^{
progress ? progress(uploadProgress) : nil;
});
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (_isOpenLog) {MYLog(@"responseObject = %@",responseObject);}
[[self allSessionTask] removeObject:task];
success ? success(responseObject) : nil;
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (_isOpenLog) {MYLog(@"error = %@",error);}
[[self allSessionTask] removeObject:task];
failure ? failure(error) : nil;
}];
// 添加sessionTask到数组
sessionTask ? [[self allSessionTask] addObject:sessionTask] : nil ;
return sessionTask;
}
#pragma mark - 上传GIF
+ (NSURLSessionTask *)uploadGIFWithURL:(NSString *)URL
parameters:(id)parameters
name:(NSString *)name
gifData:(NSData *)gifData
success:(MLHttpRequestSuccess)success
failure:(MLHttpRequestFailed)failure {
NSURLSessionTask *sessionTask = [_sessionManager POST:URL parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
// 默认图片的文件名, 若fileNames为nil就使用
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyyMMddHHmmss";
NSString *str = [formatter stringFromDate:[NSDate date]];
NSString *imageFileName = NSStringFormat(@"%@.gif", str);
[formData appendPartWithFileData:gifData
name:name
fileName:imageFileName
mimeType:@"gif"];
} progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (_isOpenLog) {MYLog(@"responseObject = %@",responseObject);}
[[self allSessionTask] removeObject:task];
success ? success(responseObject) : nil;
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (_isOpenLog) {MYLog(@"error = %@",error);}
[[self allSessionTask] removeObject:task];
failure ? failure(error) : nil;
}];
// 添加sessionTask到数组
sessionTask ? [[self allSessionTask] addObject:sessionTask] : nil ;
return sessionTask;
}
#pragma mark - 上传多张图片
+ (NSURLSessionTask *)uploadImagesWithURL:(NSString *)URL
parameters:(id)parameters
name:(NSString *)name
images:(NSArray<UIImage *> *)images
fileNames:(NSArray<NSString *> *)fileNames
imageScale:(CGFloat)imageScale
imageType:(NSString *)imageType
progress:(MLHttpProgress)progress
success:(MLHttpRequestSuccess)success
failure:(MLHttpRequestFailed)failure {
//新增验签
NSString *timestamp = [BJEncryptionTool getNowTimeTimestamp];
NSString *app_sign = [BJEncryptionTool getSignWith:timestamp];
[_sessionManager.requestSerializer setValue:C_string(timestamp) forHTTPHeaderField:@"timestamp"];
[_sessionManager.requestSerializer setValue:C_string(app_sign) forHTTPHeaderField:@"app-sign"];
NSURLSessionTask *sessionTask = [_sessionManager POST:URL parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
for (NSUInteger i = 0; i < images.count; i++) {
// 图片经过等比压缩后得到的二进制文件
NSData *imageData = UIImageJPEGRepresentation(images[i], imageScale ?: 1.f);
// 默认图片的文件名, 若fileNames为nil就使用
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyyMMddHHmmss";
NSString *str = [formatter stringFromDate:[NSDate date]];
NSString *imageFileName = NSStringFormat(@"%@%ld.%@",str,i,imageType?:@"jpg");
[formData appendPartWithFileData:imageData
name:name
fileName:fileNames ? NSStringFormat(@"%@.%@",fileNames[i],imageType?:@"jpg") : imageFileName
mimeType:NSStringFormat(@"image/%@",imageType ?: @"jpg")];
}
} progress:^(NSProgress * _Nonnull uploadProgress) {
//上传进度
dispatch_sync(dispatch_get_main_queue(), ^{
progress ? progress(uploadProgress) : nil;
});
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (_isOpenLog) {MYLog(@"responseObject = %@",responseObject);}
[[self allSessionTask] removeObject:task];
success ? success(responseObject) : nil;
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (_isOpenLog) {MYLog(@"error = %@",error);}
[[self allSessionTask] removeObject:task];
failure ? failure(error) : nil;
}];
// 添加sessionTask到数组
sessionTask ? [[self allSessionTask] addObject:sessionTask] : nil ;
return sessionTask;
}
#pragma mark - 上传多张图片及语音
+ (NSURLSessionTask *)uploadImagesWithURL:(NSString *)URL
parameters:(id)parameters
name:(NSString *)name
images:(NSArray<UIImage *> *)images
fileNames:(NSArray<NSString *> *)fileNames
imageScale:(CGFloat)imageScale
imageType:(NSString *)imageType
audio:(NSString *)audiofilePath
progress:(MLHttpProgress)progress
success:(MLHttpRequestSuccess)success
failure:(MLHttpRequestFailed)failure {
NSURLSessionTask *sessionTask = [_sessionManager POST:URL parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
if (images.count > 0){
for (NSUInteger i = 0; i < images.count; i++) {
// 图片经过等比压缩后得到的二进制文件
NSData *imageData = UIImageJPEGRepresentation(images[i], imageScale ?: 1.f);
// 默认图片的文件名, 若fileNames为nil就使用
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyyMMddHHmmss";
NSString *str = [formatter stringFromDate:[NSDate date]];
NSString *imageFileName = NSStringFormat(@"%@%ld.%@",str,i,imageType?:@"jpg");
[formData appendPartWithFileData:imageData
name:NSStringFormat(@"img%ld",i + 1)
fileName:fileNames ? NSStringFormat(@"%@.%@",fileNames[i],imageType?:@"jpg") : imageFileName
mimeType:NSStringFormat(@"image/%@",imageType ?: @"jpg")];
}
}
} progress:^(NSProgress * _Nonnull uploadProgress) {
//上传进度
dispatch_sync(dispatch_get_main_queue(), ^{
progress ? progress(uploadProgress) : nil;
});
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (_isOpenLog) {MYLog(@"responseObject = %@",responseObject);}
[[self allSessionTask] removeObject:task];
success ? success(responseObject) : nil;
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (_isOpenLog) {MYLog(@"error = %@",error);}
[[self allSessionTask] removeObject:task];
failure ? failure(error) : nil;
}];
// 添加sessionTask到数组
sessionTask ? [[self allSessionTask] addObject:sessionTask] : nil ;
return sessionTask;
}
#pragma mark - 下载文件
+ (NSURLSessionTask *)downloadWithURL:(NSString *)URL
fileDir:(NSString *)fileDir
progress:(MLHttpProgress)progress
success:(void(^)(NSString *))success
failure:(MLHttpRequestFailed)failure {
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:URL]];
__block NSURLSessionDownloadTask *downloadTask = [_sessionManager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
//下载进度
dispatch_sync(dispatch_get_main_queue(), ^{
progress ? progress(downloadProgress) : nil;
});
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
//拼接缓存目录
NSString *downloadDir = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:fileDir ? fileDir : @"Download"];
//打开文件管理器
NSFileManager *fileManager = [NSFileManager defaultManager];
//创建Download目录
[fileManager createDirectoryAtPath:downloadDir withIntermediateDirectories:YES attributes:nil error:nil];
//拼接文件路径
NSString *filePath = [downloadDir stringByAppendingPathComponent:response.suggestedFilename];
//返回文件位置的URL路径
return [NSURL fileURLWithPath:filePath];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
[[self allSessionTask] removeObject:downloadTask];
if(failure && error) {failure(error) ; return ;};
success ? success(filePath.absoluteString /** NSURL->NSString*/) : nil;
}];
//开始下载
[downloadTask resume];
// 添加sessionTask到数组
downloadTask ? [[self allSessionTask] addObject:downloadTask] : nil ;
return downloadTask;
}
/**
存储着所有的请求task数组
*/
+ (NSMutableArray *)allSessionTask {
if (!_allSessionTask) {
_allSessionTask = [[NSMutableArray alloc] init];
}
return _allSessionTask;
}
#pragma mark - 初始化AFHTTPSessionManager相关属性
/**
开始监测网络状态
*/
+ (void)load {
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
}
/**
* 所有的HTTP请求共享一个AFHTTPSessionManager
* 原理参考地址:http://www.jianshu.com/p/5969bbb4af9f
*/
+ (void)initialize {
_sessionManager = [AFHTTPSessionManager manager];
_sessionManager.requestSerializer.timeoutInterval = 30.f;
// _sessionManager.responseSerializer = [AFHTTPResponseSerializer serializer];
// _sessionManager.requestSerializer = [AFHTTPRequestSerializer serializer];
// _sessionManager.responseSerializer = [AFHTTPResponseSerializer serializer];
_sessionManager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/html", @"text/json", @"text/plain", @"text/javascript", @"text/xml", @"image/*", nil];
// 打开状态栏的等待菊花
// [AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
}
#pragma mark - 重置AFHTTPSessionManager相关属性
+ (void)setAFHTTPSessionManagerProperty:(void (^)(AFHTTPSessionManager *))sessionManager {
sessionManager ? sessionManager(_sessionManager) : nil;
}
+ (void)setRequestSerializer:(MLRequestSerializer)requestSerializer {
_sessionManager.requestSerializer = requestSerializer==MLRequestSerializerHTTP ? [AFHTTPRequestSerializer serializer] : [AFJSONRequestSerializer serializer];
}
+ (void)setResponseSerializer:(MLResponseSerializer)responseSerializer {
_sessionManager.responseSerializer = responseSerializer==MLResponseSerializerHTTP ? [AFHTTPResponseSerializer serializer] : [AFJSONResponseSerializer serializer];
}
+ (void)setRequestTimeoutInterval:(NSTimeInterval)time {
_sessionManager.requestSerializer.timeoutInterval = time;
}
+ (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field {
[_sessionManager.requestSerializer setValue:value forHTTPHeaderField:field];
}
+ (void)openNetworkActivityIndicator:(BOOL)open {
// [[AFNetworkActivityIndicatorManager sharedManager] setEnabled:open];
}
+ (void)setSecurityPolicyWithCerPath:(NSString *)cerPath validatesDomainName:(BOOL)validatesDomainName {
NSData *cerData = [NSData dataWithContentsOfFile:cerPath];
// 使用证书验证模式
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
// 如果需要验证自建证书(无效证书)需要设置为YES
securityPolicy.allowInvalidCertificates = YES;
// 是否需要验证域名默认为YES;
securityPolicy.validatesDomainName = validatesDomainName;
securityPolicy.pinnedCertificates = [[NSSet alloc] initWithObjects:cerData, nil];
[_sessionManager setSecurityPolicy:securityPolicy];
}
@end
#pragma mark - NSDictionary,NSArray的分类
/*
************************************************************************************
*新建NSDictionary与NSArray的分类, 控制台打印json数据中的中文
************************************************************************************
*/
#ifdef DEBUG
@implementation NSArray (ML)
- (NSString *)descriptionWithLocale:(id)locale {
NSMutableString *strM = [NSMutableString stringWithString:@"(\n"];
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[strM appendFormat:@"\t%@,\n", obj];
}];
[strM appendString:@")"];
return strM;
}
@end
@implementation NSDictionary (ML)
- (NSString *)descriptionWithLocale:(id)locale {
NSMutableString *strM = [NSMutableString stringWithString:@"{\n"];
[self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
[strM appendFormat:@"\t%@ = %@;\n", key, obj];
}];
[strM appendString:@"}\n"];
return strM;
}
@end
#endif