cdts/xdts-ios 3/TreeHole/CYHResetCode/CYH/NetworkingTool/NetworkingManager.m
2023-07-27 09:20:00 +08:00

470 lines
19 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

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.

//
// NetworkingManager.m
// SRKnow
//
// Created by CYH on 2020/7/21.
// Copyright © 2020 shirong. All rights reserved.
//
#import "NetworkingManager.h"
#import "NetworkingTool.h"
#import <AFNetworkActivityIndicatorManager.h>
#import "NetworkingInterface.h"
@interface NetworkingManager ()
///主域名是否为动态获取
@property(nonatomic, readonly, assign)BOOL isDynamicMainHost;
///主域名
@property(nonatomic, copy)NSString *mainHost;
@property(nonatomic, strong)NSMutableDictionary *scheduledRequestHeaders;
@end
@implementation NetworkingManager
@synthesize mainHost = _mainHost;
#pragma mark - 项目定制设置
///定制初始化
- (void)scheduledInit {
_isDynamicMainHost = NO;
self.networkingContextType = NetworkingContextType_Release;
///监听登录和退出登录的通知
__weak typeof(self) weakSelf = self;
[NSNotificationCenter.defaultCenter addObserverForName:LoginSuccessNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
//登录成功, 设置请求头
NSString *userToken = [LoginService token];
NSLog(@"CYH===%@", userToken);
[weakSelf setScheduleRequestHeader:@{
@"Authorization" : [@"Bearer " stringByAppendingString:userToken]
}];
}];
[NSNotificationCenter.defaultCenter addObserverForName:LogoutSuccessNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
//退出登录成功, 清空请求头
[weakSelf setScheduleRequestHeader:nil];
}];
NSString *userToken = [LoginService token];
if (userToken.length) {
[weakSelf setScheduleRequestHeader:@{
@"Authorization" : [@"Bearer " stringByAppendingString:userToken]
}];
}
[NetworkingTool setRequestSerializer:CYHRequestSerializerHTTP];
[NetworkingTool setRequestTimeout:8.0f];
[NetworkingTool setResponseSerializer:CYHResponseSerializerJSON];
// [NetworkingTool.sessionManager.requestSerializer setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
/*
_isDynamicMainHost = NO;
/定制请求头参数
NSString *token = WLUserManager.share.token.token;
token = [NSString stringWithFormat:@"Bearer%@", token];
_scheduledHeaders = @{
@"App" : @"iOS",
@"App-Model" : [WLTool getCurrentDeviceModel],
@"App-Version" : VERSION_CODE,
@"iOS_App_Version" : VERSION_CODE,
@"deviceID" : [WLTool currentIdentifier],
@"App-Channel" : @"app_store",
@"User-Agent" : @"iOS",
@"Authorization" : token
};
///定制-请求序列化格式为JSON
AFJSONRequestSerializer *jsonRequestSerializer = [AFJSONRequestSerializer serializer];
//超时设置
httpRequestSerializer.timeoutInterval = 8.0f;
NetworkingTool.sessionManager.requestSerializer = httpRequestSerializer;
[NetworkingTool.sessionManager.requestSerializer setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
///定制 - 响应序列化格式为HTTP
AFHTTPResponseSerializer *httpResponseSerializer = [AFHTTPResponseSerializer serializer];
//response可接受的内容类型
httpResponseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/html", @"text/json", @"text/javascript", @"text/plain", @"image/jpeg", nil];
NetworkingTool.sessionManager.responseSerializer = httpResponseSerializer;
*/
/** 定制安全策略
* 安全策略 - AFSecurityPolicy - AFSSLPinningMode说明
* AFSSLPinningModeNone(默认): 不使用固定证书(本地)验证服务器。直接从客户端系统中的受信任颁发机构 CA 列表中去验证
* AFSSLPinningModePublicKey: 代表会对服务器返回的证书中的PublicKey进行验证通过则通过否则不通过
* AFSSLPinningModeCertificate: 代表会对服务器返回的证书同本地证书全部进行校验,通过则通过,否则不通过
// 使用允许无效或过期的证书,默认是不允许。
NetworkingTool.sessionManager.securityPolicy.allowInvalidCertificates = YES;
// 是否验证证书中的域名domain
NetworkingTool.sessionManager.securityPolicy.validatesDomainName = NO;
// 打开状态栏的等待菊花
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
*/
}
+ (NSString *)fullUrlWithPath:(NSString *)path {
//新接口用V2,旧接口用V1
return [[self.shared mainHost] stringByAppendingFormat:@"/api/%@", path];
}
#pragma mark - 环境切换
//#ifdef DEBUG
/////调试阶段: 在这里手动修改测试环境;
//- (NetworkingContextType)getDebugNetworkingContextType {
// return NetworkingContextType_Test;
//}
//#endif
///切换环境及域名
- (void)setNetworkingContextType:(NetworkingContextType)networkingContextType {
#ifdef DEBUG //调试阶段
#else //发布阶段
// networkingContextType = NetworkingContextType_Release;
#endif
// _networkingContextType = NetworkingContextType_Test;
_networkingContextType = networkingContextType;
if (!_isDynamicMainHost) {
///不是动态获取
self.mainHost = BaseHostUrl;
return;
}
///动态获取
if (networkingContextType == NetworkingContextType_Release) {
///正式环境
///从网络获取或沙盒中获取
NSString *host = @"http://chat.yuantiyu.com";
if (!host) {
///沙盒中为nil, 网络获取并赋值给self.mainHost,并保存
[self requestMainHost];
}
return;
}
if (networkingContextType == NetworkingContextType_PreRelease) {
///预生产环境
self.mainHost = @"http://chat.yuantiyu.com";
return;
}
///测试环境
self.mainHost = @"http://chat.yuantiyu.com";
}
///主域名
//- (NSString *)mainHost {
// if (!_mainHost) {
//#ifdef DEBUG //调试阶段
// self.networkingContextType = [self getDebugNetworkingContextType];
//#else //发布阶段
// self.networkingContextType = NetworkingContextType_Release;
//#endif
// }
// return _mainHost;
//}
//+ (NSDictionary *)scheduledHeaders {
// NSMutableDictionary *dicM = [NSMutableDictionary dictionary];
//// dicM[@"X-Token"] = LQInteractorManager.sharedInstance.userInfoManager.userInfoModel.token;
// return dicM;
//}
#pragma mark - 动态获取主域名(根据项目设置)
///根据项目要求,主域名是否需要动态获取 ? (动态获取存进沙盒,每次请求检查主域名) : (写死)
- (void)requestMainHost {
[NetworkingTool BasePOST:@"" parameters:nil headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
}];
}
#pragma mark - POST
/**
* 项目定制_POST请求
* @param targetUrl url路径
* @param paramDic 参数
* @param successBlock 回调
* @param failureBlock 回调
*/
+ (nullable NSURLSessionDataTask *)scheduledPOST:(NSString *)targetUrl parameters:(nullable id)paramDic success:(nullable void (^)(NSURLSessionDataTask *task, NetResponseModel* _Nullable responseModel))successBlock failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failureBlock {
__weak typeof(self) weakSelf = self;
NSString *fullUrl = [self fullUrlWithPath:targetUrl];
NSMutableDictionary *paramDicM = [NSMutableDictionary dictionaryWithDictionary:paramDic];
///添加其他参数
[weakSelf scheduledParam:paramDicM];
return [NetworkingTool BasePOST:fullUrl parameters:paramDicM headers:NetworkingManager.shared.scheduledRequestHeaders progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
///第一层返回信息数据
NetResponseModel *responseModel = [weakSelf modelWithJSON:responseObject];
/*
if (responseModel.code == 1002) {
///未登录
[GraceHudTool.sharedInstance showText:responseModel.msg inView:UIApplication.sharedApplication.keyWindow];
// [LQInteractorManager showLandingContainerViewControllerForWindowsRootViewController:LQLandingShowType_Landing];
return;
}
if (responseModel.code == 1003) {
///没有权限
[GraceHudTool.sharedInstance showText:responseModel.msg inView:UIApplication.sharedApplication.keyWindow];
return;
}
if (responseModel.code == 1001) {
///其他错误
[GraceHudTool.sharedInstance showText:responseModel.msg inView:UIApplication.sharedApplication.keyWindow];
return;
}
*/
///第二层返回信息: 业务真正需要的数据
// NetResponseModel *responseDataModel = [NetResponseModel new];
// responseDataModel.code = responseModel.code;
// responseDataModel.data = responseModel.data[@"info"];
// responseDataModel.msg = responseModel.msg;
if (responseModel.code != 0) {
///其他错误
// [GraceHudTool.sharedInstance showText:responseModel.message inView:UIApplication.sharedApplication.windows.firstObject];
return;
}
if (successBlock) {
successBlock(task, responseModel);
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (failureBlock) {
failureBlock(task, error);
return;
}
// [GraceHudTool.sharedInstance showText:error.domain inView:UIApplication.sharedApplication.windows.firstObject];
}];
}
#pragma mark - GET
/**
* GET请求
* @param targetUrl URL路径
* @param paramDic 参数
* @param successBlock 回调
* @param failureBlock 回调
*/
+ (nullable NSURLSessionDataTask *)scheduledGET:(NSString *)targetUrl parameters:(NSDictionary *)paramDic success:(nullable void (^)(NSURLSessionDataTask *task, NetResponseModel* _Nullable responseModel))successBlock failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failureBlock {
__weak typeof(self) weakSelf = self;
NSString *fullUrl = [self fullUrlWithPath:targetUrl];
NSMutableDictionary *paramDicM = [NSMutableDictionary dictionaryWithDictionary:paramDic];
///添加其他参数
[self scheduledParam:paramDicM];
return [NetworkingTool BaseGet:fullUrl parameters:paramDicM headers:NetworkingManager.shared.scheduledRequestHeaders progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
///第一层返回信息数据
NetResponseModel *responseModel = [weakSelf modelWithJSON:responseObject];
if (responseModel.code != 0) {
///其他错误
// [GraceHudTool.sharedInstance showText:responseModel.message inView:UIApplication.sharedApplication.windows.firstObject];
return;
}
if (successBlock) {
successBlock(task, responseModel);
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (failureBlock) {
failureBlock(task, error);
return;
}
// [GraceHudTool.sharedInstance showText:error.domain inView:UIApplication.sharedApplication.windows.firstObject];
}];
}
///定制请求参数: 添加签名
+ (void)scheduledParam:(NSMutableDictionary *)parameterM {
/*
NSString *const kRequestSalt = @"479b2e5623028967e78ee79aa5aa8a6613d6e4e93d83fa50252b9984af5db4e0c00e7de564d12f6aa4deec7837e2829c";
NSString *app_name = @"iOS";
NSString *app_secret = kRequestSalt;
NSString *time = [NSString stringWithFormat:@"%.0f", [[NSDate date] timeIntervalSince1970]];
[parameterM setObject:app_name forKey:@"app_name"];
[parameterM setObject:time forKey:@"time"];
[parameterM setObject:app_secret forKey:@"app_secret"];
[parameterM setObject:@"1" forKey:@"check_sign"];
//对parameterM根据key进行升序排序==>sign.
NSArray *sortKeys = [parameterM allKeysSorted];
NSMutableString *sign = [NSMutableString string];
[sortKeys enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSString *value = parameterM[obj];
if ([value isKindOfClass:NSString.class]) {
value = [value stringByURLEncode];
// value = value.wl_encodingUrlParameterString;
}
[sign appendFormat:@"%@=%@%@", obj, value, ((idx == (sortKeys.count-1)) ? @"" : @"&")];
}];
[parameterM setObject:sign.md5String forKey:@"sign"];
[parameterM removeObjectForKey:@"app_secret"];
*/
}
#pragma mark - 上传
/// upload上传文件
/// @param url 服务器URL
/// @param data 文件二进制数据
/// @param uploadProgress 上传进度回调
/// @param completionHandler 上传完成回调
+ (nullable NSURLSessionUploadTask *)scheduleUploadFile:(NSString *)url fileData:(NSData *)data progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler {
// __weak typeof(self) weakSelf = self;
NSString *fullUrl = [self fullUrlWithPath:url];
// NSMutableDictionary *paramDicM = [NSMutableDictionary dictionaryWithDictionary:paramDic];
///添加其他参数
// [self scheduledParam:paramDicM];
return [NetworkingTool upload:fullUrl fileData:data progress:uploadProgress completionHandler:completionHandler];
}
/// upload上传文件
/// @param url 服务器URL
/// @param data 文件二进制数据
/// @param uploadProgress 上传进度回调
/// @param completionHandler 上传完成回调
+ (void)scheduleUploadFiles:(NSString *)url fileDatas:(NSArray <NSData *>*)datas progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress completionHandler:(void (^)(NSArray <NSString *>*fileUrlPaths))completionHandler {
NSMutableArray *paths = [NSMutableArray array];
dispatch_queue_t globalQuene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
for (NSData *data in datas) {
dispatch_group_enter(group);
dispatch_async(globalQuene, ^{
[self scheduleUploadFile:url fileData:data progress:uploadProgress completionHandler:^(NSURLResponse * _Nonnull response, id _Nonnull responseObject, NSError * _Nonnull error) {
NSLog(@"%@", response);
if (!error) {
[paths addObject:responseObject];
}
dispatch_group_leave(group);
}];
});
}
//一直等待完成
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"完成");
if (completionHandler) {
completionHandler(paths);
}
});
}
/// From表单提交
/// 上传数据 - POST请求 - Form表单提交数据(创建并运行一个包含多部分 "POST "请求的 "NSURLSessionDataTask"。)
/// @param URLString URLString
/// @param paramDic 参数
/// @param headerDic 附加到这个请求的默认头部的头部
/// @param block 一个接受单个参数并将数据附加到HTTP body的块。block参数是一个采用`AFMultipartFormData`协议的对象。
/// @param uploadProgress 上传进度回调
/// @param successBlock 成功回调 ---> Model
/// @param failureBlock 失败回调
+ (nullable NSURLSessionDataTask *)upload_POST:(NSString *)URLString parameters:(nullable id)paramDic headers:(nullable NSDictionary <NSString *, NSString *> *)headerDic constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress success:(nullable void (^)(NSURLSessionDataTask *task, NetResponseModel* _Nullable responseModel))successBlock failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failureBlock {
NSString *fullUrl = [self fullUrlWithPath:URLString];
// [BaseUrl stringByAppendingString:URLString];
__weak typeof(self) weakSelf = self;
return [NetworkingTool upload_BasePOST:fullUrl parameters:paramDic headers:headerDic constructingBodyWithBlock:block progress:uploadProgress success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NetResponseModel *responseModel = [weakSelf modelWithJSON:responseObject];
if (successBlock) {
successBlock(task, responseModel);
}
} failure:failureBlock];
}
+ (NetResponseModel *)modelWithJSON:(NSDictionary *)dic {
return [NetResponseModel yy_modelWithJSON:dic];
}
//MARK: - Get&Set
- (void)setScheduleRequestHeader:(NSDictionary *)reqHeader {
[self.scheduledRequestHeaders removeAllObjects];
[self.scheduledRequestHeaders setDictionary:reqHeader];
self.scheduledRequestHeaders[@"device_brand"] = @"Apple";
self.scheduledRequestHeaders[@"device_model"] = [THNetworkInterfaceService deviceModel];
self.scheduledRequestHeaders[@"app_version_name"] = [THNetworkInterfaceService version];
self.scheduledRequestHeaders[@"app_version_code"] = [THNetworkInterfaceService bundleVersion];
self.scheduledRequestHeaders[@"interface_version"] = [THNetworkInterfaceService version];;
self.scheduledRequestHeaders[@"device_platform"] = @"iOS";
self.scheduledRequestHeaders[@"os_version"] = [THNetworkInterfaceService deviceSystemVersion];
}
- (void)setMainHost:(NSString *)mainHost {
_mainHost = mainHost;
///发送通知: 第一次赋值 或 被修改
[NSNotificationCenter.defaultCenter postNotificationName:MainHostURL_DidChangeNotifyKEY object:nil userInfo:nil];
}
- (NSMutableDictionary *)scheduledRequestHeaders {
if (!_scheduledRequestHeaders) {
_scheduledRequestHeaders = [NSMutableDictionary dictionary];
}
return _scheduledRequestHeaders;
}
#pragma mark - 单例
+ (instancetype)shared {
return [[self alloc] init];
}
// 创建静态对象 防止外部访问
static NetworkingManager *_instance;
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (_instance == nil) {
_instance = [super allocWithZone:zone];
[_instance scheduledInit];
}
});
return _instance;
}
// 为了严谨也要重写copyWithZone 和 mutableCopyWithZone
-(id)copyWithZone:(NSZone *)zone {
return _instance;
}
-(id)mutableCopyWithZone:(NSZone *)zone {
return _instance;
}
@end