// // QXRequset.m // YSDTrucksProject // // Created by 党凯 on 2020/7/1. // Copyright © 2020 党凯. All rights reserved. // #import "QXRequest.h" #import "QXFileManager.h" #import #import "OpenUDID.h" static AFNetworkReachabilityStatus AFNetWorkStatus; //网络状态 static NSInteger HTTP_LOGINLOSE_CODE = 301; /// 房间接口code 202 static NSInteger HTTP_ROOM_ERROR_CODE = 202; static NSInteger HTTP_SUCCESS_CODE = 1; static NSInteger HTTP_ERROR_CODE = 0; @implementation QXRequset +(QXRequset *)shareInstance{ static QXRequset *request = nil; static dispatch_once_t predicate; dispatch_once(&predicate, ^{ request = [[QXRequset alloc] init]; [self checkNetworkStatus]; }); return request; } - (AFHTTPSessionManager *)sharedManager { static AFHTTPSessionManager *manager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ manager = [AFHTTPSessionManager manager]; manager.responseSerializer = [AFJSONResponseSerializer serializer]; manager.responseSerializer.acceptableContentTypes = [NSSet setWithArray:@[@"application/json", @"text/html", @"text/json", @"text/plain", @"text/javascript", @"text/xml", @"image/*", @"application/octet-stream", @"application/zip"]]; manager.requestSerializer = [AFJSONRequestSerializer serializer]; AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone]; // // 是否允许自签名证书(生产环境必须设为 NO) // securityPolicy.allowInvalidCertificates = YES; // // 是否验证证书域名是否匹配(强烈建议开启) // securityPolicy.validatesDomainName = NO; // // 加载本地证书 // NSData *certData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"server1" ofType:@"cer"]]; // securityPolicy.pinnedCertificates = [NSSet setWithObject:certData]; // manager.securityPolicy = securityPolicy; manager.requestSerializer.timeoutInterval = 10; }); return manager; } + (void)checkNetworkStatus { AFNetWorkStatus = AFNetworkReachabilityStatusUnknown; AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager]; [manager startMonitoring]; [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { switch (status) { case AFNetworkReachabilityStatusUnknown: { // 未知网络 AFNetWorkStatus = AFNetworkReachabilityStatusUnknown; } break; case AFNetworkReachabilityStatusNotReachable: { // 没有网络 AFNetWorkStatus = AFNetworkReachabilityStatusNotReachable; } break; case AFNetworkReachabilityStatusReachableViaWWAN: { // 手机自带网络,移动流量 AFNetWorkStatus = AFNetworkReachabilityStatusReachableViaWWAN; } break; case AFNetworkReachabilityStatusReachableViaWiFi: { // WIFI AFNetWorkStatus = AFNetworkReachabilityStatusReachableViaWiFi; } } if (AFNetWorkStatus != AFNetworkReachabilityStatusNotReachable){ [[NSNotificationCenter defaultCenter] postNotificationName:noticeUserLogin object:nil]; } }]; } - (NSURLSessionTask*)getWithUrl:(NSString *)urlString parameters:(id)parameters needCache:(BOOL)needCache success:(NeQXRequsetSuccessBlock)success fail:(NeQXRequsetFailedBlock)fail { RequestCachePolicy policy = IgnoringLocalCacheData; if (needCache) { policy = CacheDataThenLoad; } return [self requestWithUrl:urlString parameters:parameters type:GET cachePolicy:policy success:success cache:success failure:fail]; } - (NSURLSessionTask*)postWithUrl:(NSString *)urlString parameters:(id)parameters needCache:(BOOL)needCache success:(NeQXRequsetSuccessBlock)success fail:(NeQXRequsetFailedBlock)fail { RequestCachePolicy policy = IgnoringLocalCacheData; if (needCache) { policy = CacheDataThenLoad; } return [self requestWithUrl:urlString parameters:parameters type:POST cachePolicy:policy success:success cache:success failure:fail]; } - (NSURLSessionTask*)putWithUrl:(NSString *)urlString parameters:(id)parameters needCache:(BOOL)needCache success:(NeQXRequsetSuccessBlock)success fail:(NeQXRequsetFailedBlock)fail { RequestCachePolicy policy = IgnoringLocalCacheData; if (needCache) { policy = CacheDataThenLoad; } return [self requestWithUrl:urlString parameters:parameters type:PUT cachePolicy:policy success:success cache:nil failure:fail]; } - (NSURLSessionTask*)deleteWithUrl:(NSString *)urlString parameters:(id)parameters needCache:(BOOL)needCache success:(NeQXRequsetSuccessBlock)success fail:(NeQXRequsetFailedBlock)fail { RequestCachePolicy policy = IgnoringLocalCacheData; if (needCache) { policy = CacheDataThenLoad; } return [self requestWithUrl:urlString parameters:parameters type:DELETE cachePolicy:policy success:success cache:nil failure:fail]; } - (NSURLSessionTask*)patchWithUrl:(NSString *)urlString parameters:(id)parameters needCache:(BOOL)needCache success:(NeQXRequsetSuccessBlock)success fail:(NeQXRequsetFailedBlock)fail { RequestCachePolicy policy = IgnoringLocalCacheData; if (needCache) { policy = CacheDataThenLoad; } return [self requestWithUrl:urlString parameters:parameters type:PATCH cachePolicy:policy success:success cache:nil failure:fail]; } - (NSURLSessionTask*)postUploadImageWithUrl:(NSString *)urlString image:(UIImage *)image parameters:(id)parameters progress:(NeQXRequsetProgressBlock)progress success:(NeQXRequsetSuccessBlock)success fail:(NeQXRequsetFailedBlock)fail { AFHTTPSessionManager *manager = [self sharedManager]; if (AFNetWorkStatus == AFNetworkReachabilityStatusNotReachable) { if (fail)fail(NOT_NETWORK_ERROR,@"无网络",nil); return nil; } #warning 请求头添加 ///请求头 NSDictionary *headers = @{}; return [manager POST:urlString parameters:parameters headers:headers constructingBodyWithBlock:^(id _Nonnull formData) { NSData *imageData = UIImagePNGRepresentation(image); NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; formatter.dateFormat = @"yyyyMMddHHmmss"; NSString *str = [formatter stringFromDate:[NSDate date]]; NSString *fileName = [NSString stringWithFormat:@"%@.jpg",str]; [formData appendPartWithFileData:imageData name:@"file" fileName:fileName mimeType:@"image/jpg"]; } progress:^(NSProgress * _Nonnull uploadProgress) { if (progress)progress(uploadProgress.fractionCompleted); } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSDictionary *dict = [self getResponseDictWith:responseObject urlString:urlString]; if (success) { success(dict); } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { if (fail){ fail(error,error.description,task); }; NSHTTPURLResponse * responses = (NSHTTPURLResponse *)task.response; NSLog(@"失败返回 --- URL : %@ \n ---错误码 = %ld \n ---详细信息 : %@",urlString,(long)responses.statusCode,error); }]; } - (NSURLSessionTask*)requestWithUrl:(NSString *)urlString parameters:(id)parameters type:(NetworkMethod)type cachePolicy:(RequestCachePolicy)policy success:(NeQXRequsetSuccessBlock)success cache:(NetResponseCache)cache failure:(NeQXRequsetFailedBlock)fail{ AFHTTPSessionManager *manager = [self sharedManager]; ///无网络直接返回失败 if (AFNetWorkStatus == AFNetworkReachabilityStatusNotReachable) { if (fail)fail(NOT_NETWORK_ERROR,@"无网络",nil); return nil; } if (!([urlString hasPrefix:@"http"] || [urlString hasPrefix:@"https"])) { urlString = [NSString stringWithFormat:@"%@%@",ServerUrl,urlString]; } NSLog(@"发起请求 --- URL : %@",urlString); //缓存,用url拼接参数作为key YYCache *myCache = [YYCache cacheWithName:@"QXCache"]; NSString *parString = parameters ? [parameters yy_modelToJSONString] : @""; NSString *cacheKey = [NSString stringWithFormat:@"%@%@", urlString, parString]; if (cache) { //获取缓存 id object = [myCache objectForKey:cacheKey]; switch (policy) { //先返回缓存,同时请求 case CacheDataThenLoad: { if (object)cache(object); break; } //忽略本地缓存直接请求 case IgnoringLocalCacheData: { break; } //有缓存就返回缓存,没有就请求 case CacheDataElseLoad: { if (object) { cache(object); return nil; } break; } //有缓存就返回缓存,从不请求(用于没有网络) case CacheDataDontLoad: { if (object)cache(object); return nil; } default: { break; } } } #warning 请求头添加 ///请求头 NSDictionary *headers = @{}; [manager.requestSerializer setValue:@"iOS" forHTTPHeaderField:@"system"]; NSString *value = [OpenUDID value]; [manager.requestSerializer setValue:value forHTTPHeaderField:@"deviceId"]; NSString*appVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; [manager.requestSerializer setValue:appVersion forHTTPHeaderField:@"App-Version"]; if ([QXGlobal shareGlobal].isLogin) { [manager.requestSerializer setValue:[QXGlobal shareGlobal].loginModel.token forHTTPHeaderField:@"token"]; }else{ [manager.requestSerializer setValue:@"" forHTTPHeaderField:@"token"]; } switch (type) { case GET: { return [manager GET:urlString parameters:parameters headers:headers progress:^(NSProgress * _Nonnull downloadProgress) { } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSDictionary *dict = [self getResponseDictWith:responseObject urlString:urlString]; int code = [dict[@"code"] intValue]; if (code == HTTP_LOGINLOSE_CODE) { [[QXGlobal shareGlobal] logOut]; NSString *msg = [NSString stringWithFormat:@"%@",dict[@"msg"]]; fail(nil,msg,task); return; } if (code == HTTP_ERROR_CODE) { NSString *msg = [NSString stringWithFormat:@"%@",dict[@"msg"]]; fail(nil,msg,task); return; } if (success) { success(dict); } if (cache) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ if (policy != IgnoringLocalCacheData) { [myCache setObject:dict forKey:cacheKey]; } }); } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { if (fail){ fail(error,error.description,task); }; NSHTTPURLResponse * responses = (NSHTTPURLResponse *)task.response; NSLog(@"失败返回 --- URL : %@ \n ---错误码 = %ld \n ---详细信息 : %@",urlString,(long)responses.statusCode,error); }]; } break; case POST: { [manager.requestSerializer setValue:@"form-data" forHTTPHeaderField:@"Content-type"]; return [manager POST:urlString parameters:nil headers:@{} constructingBodyWithBlock:^(id _Nonnull formData) { for (NSString *key in [parameters allKeys]) { id value = [parameters objectForKey:key]; if ([value isKindOfClass:[NSString class]]) { [formData appendPartWithFormData:[[parameters objectForKey:key] dataUsingEncoding:NSUTF8StringEncoding] name:key]; continue; } if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSMutableArray class]]) { NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[parameters objectForKey:key] options:(NSJSONWritingPrettyPrinted) error:nil]; [formData appendPartWithFormData:jsonData name:key]; continue; } if ([value isKindOfClass:[NSNumber class]]) { NSNumber *number = (NSNumber *)value; NSString *numberString = number.stringValue; NSData*stringData = [numberString dataUsingEncoding:NSUTF8StringEncoding]; [formData appendPartWithFormData:stringData name:key]; continue; } } } progress:^(NSProgress * _Nonnull uploadProgress) { } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSDictionary *dict = [self getResponseDictWith:responseObject urlString:urlString]; int code = [dict[@"code"] intValue]; if (code == HTTP_LOGINLOSE_CODE) { [[QXGlobal shareGlobal] logOut]; NSString *msg = [NSString stringWithFormat:@"%@",dict[@"msg"]]; fail(nil,msg,task); return; } if (code == HTTP_ERROR_CODE) { NSString *msg = [NSString stringWithFormat:@"%@",dict[@"msg"]]; fail(nil,msg,task); return; } if (success) { success(dict); } if (cache) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ if (policy != IgnoringLocalCacheData) { [myCache setObject:dict forKey:cacheKey]; } }); } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { if (fail){ fail(error,error.localizedDescription,task); }; NSHTTPURLResponse * responses = (NSHTTPURLResponse *)task.response; NSLog(@"失败返回 --- URL : %@ \n ---错误码 = %ld \n ---详细信息 : %@",urlString,(long)responses.statusCode,error); }]; } break; case PUT: { return [manager PUT:urlString parameters:parameters headers:headers success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSDictionary *dict = [self getResponseDictWith:responseObject urlString:urlString]; if (success) { success(dict); } if (cache) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ if (policy != IgnoringLocalCacheData) { [myCache setObject:dict forKey:cacheKey]; } }); } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { if (fail){ fail(error,error.description,task); }; NSHTTPURLResponse * responses = (NSHTTPURLResponse *)task.response; NSLog(@"失败返回 --- URL : %@ \n ---错误码 = %ld \n ---详细信息 : %@",urlString,(long)responses.statusCode,error); }]; } break; case DELETE: { return [manager DELETE:urlString parameters:parameters headers:headers success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSDictionary *dict = [self getResponseDictWith:responseObject urlString:urlString]; if (success) { success(dict); } if (cache) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ if (policy != IgnoringLocalCacheData) { [myCache setObject:dict forKey:cacheKey]; } }); } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { if (fail){ fail(error,error.description,task); }; NSHTTPURLResponse * responses = (NSHTTPURLResponse *)task.response; NSLog(@"失败返回 --- URL : %@ \n ---错误码 = %ld \n ---详细信息 : %@",urlString,(long)responses.statusCode,error); }]; } break; case PATCH: { return [manager PATCH:urlString parameters:parameters headers:headers success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSDictionary *dict = [self getResponseDictWith:responseObject urlString:urlString]; if (success) { success(dict); } if (cache) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ if (policy != IgnoringLocalCacheData) { [myCache setObject:dict forKey:cacheKey]; } }); } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { if (fail){ fail(error,error.description,task); }; NSHTTPURLResponse * responses = (NSHTTPURLResponse *)task.response; NSLog(@"失败返回 --- URL : %@ \n ---错误码 = %ld \n ---详细信息 : %@",urlString,(long)responses.statusCode,error); }]; } break; default: break; } } //对返回数据做处理 -(NSDictionary*)getResponseDictWith:(id)responseObject urlString:(NSString*)urlString{ NSDictionary *dictObj; if ([responseObject isKindOfClass:[NSDictionary class]]) { dictObj = responseObject; NSLog(@"成功返回 --- URL : %@ \n %@",urlString,responseObject); }else{ NSString *responseJson = [[NSString alloc]initWithData:responseObject encoding:NSUTF8StringEncoding]; dictObj = [responseJson jsonValueDecoded]; NSLog(@"成功返回 --- URL : %@ \n %@",urlString,dictObj); } return dictObj; } /// 下载视频 - (void)downloadVideoPlayerWithUrl:(NSString *)url completion:(void (^)(BOOL result, NSString * fileName))completion { if (![url isExist]) { if (completion) { completion(NO, nil); } return; } NSString *path = [QXFileManager createLocalSourceVideoDirectory]; NSString *fileNamePath = [path stringByAppendingPathComponent:url.lastPathComponent]; if ([QXFileManager isExistsFileWithFilePath:fileNamePath]) { if (completion) { completion(YES, url.lastPathComponent); } return; } [self downloadDataWithUrl:url fileNamePath:fileNamePath localSourceDir:path completion:completion]; } /// 下载资源 - (void)downloadDataWithUrl:(NSString *)url fileNamePath:(NSString *)fileNamePath localSourceDir:(NSString *)localSourceDir completion:(void (^)(BOOL, NSString * _Nullable))completion { if (![url isExist] || ![fileNamePath isExist] || ![localSourceDir isExist]) { if (completion) { completion(NO, nil); } return; } NSURLSessionTask *task = [self downloadApi:url filePath:localSourceDir progress:^(NSProgress * _Nonnull downloadProgress) { NSLog(@"downloadProgress == %@",downloadProgress); } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) { if ([QXFileManager isExistsFileWithFilePath:fileNamePath]) { if (completion) { completion(YES, url.lastPathComponent); } }else {// 下载失败 if (completion) { completion(NO, nil); } } }]; [task resume]; } - (NSURLSessionTask *)downloadApi:(NSString *)url filePath: (NSString *)filePath progress:(nullable void (^)(NSProgress * _Nonnull))downloadProgress completionHandler: (QXDownloadCompletionHandler)completionHandler{ return [self downloadApi:url filePath:filePath fileName:url.lastPathComponent progress:downloadProgress completionHandler:completionHandler]; } - (NSURLSessionTask *)downloadApi:(NSString *)url filePath:(NSString *)filePath fileName:(NSString *)fileName progress:(void (^)(NSProgress * _Nonnull))downloadProgress completionHandler:(QXDownloadCompletionHandler)completionHandler { AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone]; manager.securityPolicy = policy; NSURLRequest *requst = [NSURLRequest requestWithURL:[NSURL URLWithString:url]]; return [manager downloadTaskWithRequest:requst progress:downloadProgress destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) { NSString *realPath = [filePath stringByAppendingPathComponent:fileName]; return [NSURL fileURLWithPath:realPath]; } completionHandler:completionHandler]; } @end