470 lines
19 KiB
Objective-C
470 lines
19 KiB
Objective-C
//
|
||
// 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
|
||
|
||
|