Files
real-e-party-iOS/YuMi/Network/HttpRequestHelper.m
edwinQQQ a35a711be6 chore: Initial clean commit
- Removed YuMi/Library/ (138 MB, not tracked)
- Removed YuMi/Resources/ (23 MB, not tracked)
- Removed old version assets (566 files, not tracked)
- Excluded Pods/, xcuserdata/ and other build artifacts
- Clean repository optimized for company server deployment
2025-10-09 16:19:14 +08:00

528 lines
21 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.

//
// HttpRequestHelper.m
// YUMI
//
// Created by zu on 2021/9/3.
//
#import "HttpRequestHelper.h"
#import "YYUtility.h"
#import "AccountInfoStorage.h"
#import "YYReachability.h"
#import <AFNetworking.h>
#import "YUMIMacroUitls.h"
#import "MSParamsDecode.h"
#import "NSData+GZIP.h"
#import <Bugly/Bugly.h>
#import "BuglyManager.h"
@implementation HttpRequestHelper
+(AFHTTPSessionManager *)requestManager
{
static AFHTTPSessionManager *manager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
configuration.HTTPShouldUsePipelining = YES; // 启用 HTTP/2 pipelining
configuration.HTTPMaximumConnectionsPerHost = 15; // 提升并发
manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:[HttpRequestHelper getHostUrl]]
sessionConfiguration:configuration];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:
@"application/json",
@"text/json",
@"text/javascript",
@"text/html",
@"text/plain",
@"image/jpeg",
@"image/png", nil];
manager.requestSerializer.HTTPShouldHandleCookies = YES;
manager.requestSerializer.timeoutInterval = 60;
// 声明开启 gzip 和 br
[manager.requestSerializer setValue:@"gzip, br" forHTTPHeaderField:@"Accept-Encoding"];
// 确保所有请求走 HTTPS避免降级到 HTTP/1.1
manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
manager.securityPolicy.allowInvalidCertificates = NO;
manager.securityPolicy.validatesDomainName = YES;
});
return manager;
}
+(NSString *)getHostUrl{
#if DEBUG
NSString *isProduction = [[NSUserDefaults standardUserDefaults]valueForKey:@"kIsProductionEnvironment"];
if([isProduction isEqualToString:@"YES"]){
return API_HOST_URL;
}
return API_HOST_TEST_URL;
#else
return API_HOST_URL;
#endif
}
+ (void)GET:(NSString *)method
params:(NSDictionary *)params
success:(void (^)(BaseModel *data))success
failure:(void (^)(NSInteger resCode, NSString *message))failure
{
if ([self checkNetworkStatusWithFailure:^{
failure(-1, YMLocalizedString(@"HttpRequestHelper0"));
}]) {
return;
}
[self configHeaders];
AFHTTPSessionManager *manager = [HttpRequestHelper requestManager];
NSString *key = @"NeedChangeTimeOut";
NSMutableDictionary *editParam = [params mutableCopy];
if ([editParam.allKeys containsObject:key]) {
NSInteger timeout = [[editParam objectForKey:key] integerValue];
[editParam removeObjectForKey:key];
if (timeout > 0) {
manager.requestSerializer.timeoutInterval = timeout;
}
}
else {
manager.requestSerializer.timeoutInterval = 60;
}
editParam = [MSParamsDecode msDecodeParams:editParam];
params = [self configBaseParmars:editParam];
#if DEBUG
// 构建完整的 URL
NSString *baseUrl = [HttpRequestHelper getHostUrl];
NSString *fullUrl = [NSString stringWithFormat:@"%@/%@", baseUrl, method];
// 构建查询字符串
NSMutableArray *queryItems = [NSMutableArray array];
[params enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
[queryItems addObject:[NSString stringWithFormat:@"%@=%@", key, obj]];
}];
NSString *queryString = [queryItems componentsJoinedByString:@"&"];
if (queryString.length > 0) {
fullUrl = [NSString stringWithFormat:@"%@?%@", fullUrl, queryString];
}
NSLog(@"\n🌐 API Request Info:");
NSLog(@"📍 Full URL: %@", fullUrl);
NSLog(@"🔧 Method: %@", method);
NSLog(@"📦 Parameter Type: queryParameters");
NSLog(@"📋 Parameters: %@\n", params);
#endif
@kWeakify(self);
[manager GET:method parameters:params headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
BaseModel *baseModel = [BaseModel modelWithDictionary:responseObject];
#if DEBUG
NSLog(@"%@ - \n%@\n", method, [baseModel toJSONString]);
#else
#endif
success(baseModel);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
@kStrongify(self);
[self handleNetError:error method:method failure:failure];
}];
}
+ (void)POST:(NSString *)method
params:(NSDictionary *)params
success:(void (^)(BaseModel *data))success
failure:(void (^)(NSInteger resCode, NSString *message))failure
{
if ([AFNetworkReachabilityManager sharedManager].networkReachabilityStatus == 0) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
failure(-1, YMLocalizedString(@"HttpRequestHelper0"));
});
return;
}
// [self configHeaders];
AFHTTPSessionManager *manager = [HttpRequestHelper requestManager];
params = [MSParamsDecode msDecodeParams:[params mutableCopy] ];
params = [self configBaseParmars:params];
#if DEBUG
// 构建完整的 URL
NSString *baseUrl = [HttpRequestHelper getHostUrl];
NSString *fullUrl = [NSString stringWithFormat:@"%@/%@", baseUrl, method];
NSLog(@"\n🌐 API Request Info:");
NSLog(@"📍 Full URL: %@", fullUrl);
NSLog(@"🔧 Method: %@", method);
NSLog(@"📦 Parameter Type: bodyParameters");
NSLog(@"📋 Parameters: %@\n", params);
#else
#endif
[manager POST:method parameters:params headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
BaseModel *baseModel = [BaseModel modelWithDictionary:responseObject];
#if DEBUG
NSLog(@"\n%@", [baseModel toJSONString]);
#else
#endif
success(baseModel);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
[self handleNetError:error method:method failure:failure];
}];
}
+ (void)__POST:(NSString *)method
params:(NSDictionary *)params
success:(void (^)(BaseModel *data))success
failure:(void (^)(NSInteger resCode, NSString *message))failure
{
if ([self checkNetworkStatusWithFailure:^{
failure(-1, YMLocalizedString(@"HttpRequestHelper0"));
}]) {
return;
}
[self configHeaders];
AFHTTPSessionManager *manager = [HttpRequestHelper requestManager];
params = [MSParamsDecode msDecodeParams:[params mutableCopy] ];
params = [self configBaseParmars:params];
#if DEBUG
NSLog(@"\nmethod:\n%@\nparameter:\n%@\n 超時:%@",
method,
params,
@(manager.session.configuration.timeoutIntervalForRequest));
#else
#endif
// 将 NSDictionary 转换为 JSON
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:nil];
// Gzip 压缩数据
NSData *gzipData = [jsonData gzippedData];
@kWeakify(self);
[manager POST:method
parameters:params
headers:nil
constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
[formData appendPartWithFormData:gzipData name:@"data"];
}
progress:nil
success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
BaseModel *baseModel = [BaseModel modelWithDictionary:responseObject];
#if DEBUG
NSLog(@"%@ - \n%@\n", method, [baseModel toJSONString]);
#else
#endif
success(baseModel);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
#if DEBUG
NSLog(@"%@ - \n%@\n", method, error);
#else
#endif
@kStrongify(self);
[self handleNetError:error method:method failure:failure];
}];
}
+ (void)DELETE:(NSString *)method
params:(NSDictionary *)params
success:(void (^)(BaseModel *data))success
failure:(void (^)(NSInteger resCode, NSString *message))failure
{
if ([self checkNetworkStatusWithFailure:^{
failure(-1, YMLocalizedString(@"HttpRequestHelper0"));
}]) {
return;
}
// [self configHeaders];
params = [MSParamsDecode msDecodeParams:[params mutableCopy] ];
params = [self configBaseParmars:params];
AFHTTPSessionManager *manager = [HttpRequestHelper requestManager];
#if DEBUG
// 构建完整的 URL
NSString *baseUrl = [HttpRequestHelper getHostUrl];
NSString *fullUrl = [NSString stringWithFormat:@"%@/%@", baseUrl, method];
// 构建查询字符串
NSMutableArray *queryItems = [NSMutableArray array];
[params enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
[queryItems addObject:[NSString stringWithFormat:@"%@=%@", key, obj]];
}];
NSString *queryString = [queryItems componentsJoinedByString:@"&"];
if (queryString.length > 0) {
fullUrl = [NSString stringWithFormat:@"%@?%@", fullUrl, queryString];
}
NSLog(@"\n🌐 API Request Info:");
NSLog(@"📍 Full URL: %@", fullUrl);
NSLog(@"🔧 Method: %@", method);
NSLog(@"📦 Parameter Type: queryParameters");
NSLog(@"📋 Parameters: %@\n", params);
#else
#endif
@kWeakify(self);
[manager DELETE:method parameters:params headers:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
BaseModel *baseModel = [BaseModel modelWithDictionary:responseObject];
#if DEBUG
NSLog(@"\n%@\n", [baseModel toJSONString]);
#else
#endif
success(baseModel);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
@kStrongify(self);
[self handleNetError:error method:method failure:failure];
}];
}
+ (void)request:(NSString *)url
method:(HttpRequestHelperMethod)method
params:(NSDictionary *)params
success:(void (^)(BaseModel *data))success
failure:(void (^)(NSInteger resCode, NSString *message))failure
{
switch (method) {
case HttpRequestHelperMethodGET: {
[self GET:url params:params success:success failure:failure];
}
break;
case HttpRequestHelperMethodPOST:{
[self POST:url params:params success:success failure:failure];
}
break;
case HttpRequestHelperMethodDELETE:{
[self DELETE:url params:params success:success failure:failure];
}
break;
}
}
+ (void)request:(NSString *)path
method:(HttpRequestHelperMethod)method
params:(NSDictionary *)params
completion:(HttpRequestHelperCompletion)completion
{
[self request:path method:method params:params success:^(BaseModel *data) {
if (completion) {
completion(data, data.code, data.message);
}
} failure:^(NSInteger resCode, NSString *message) {
if (completion) {
completion(nil, resCode, message);
}
if (resCode > 500 && resCode < 600) {
// 使用 BuglyManager 统一上报网络错误
NSString *uid = [AccountInfoStorage instance].getUid ?: @"未知用户";
NSMutableDictionary *userInfo = [params mutableCopy];
[userInfo setObject:message forKey:@"error message"];
[userInfo setObject:@(method) forKey:@"http method"];
[[BuglyManager sharedManager] reportNetworkError:uid
api:path
code:resCode
userInfo:userInfo];
}
}];
}
+ (void)configHeaders
{
AFHTTPSessionManager *client = [HttpRequestHelper requestManager];
if ([[AccountInfoStorage instance] getUid].length > 0) {
[client.requestSerializer setValue:[[AccountInfoStorage instance] getUid] forHTTPHeaderField:@"pub_uid"];
} else {
[client.requestSerializer setValue:nil forHTTPHeaderField:@"pub_uid"];
}
if ([[AccountInfoStorage instance] getTicket].length > 0) {
[client.requestSerializer setValue:[[AccountInfoStorage instance] getTicket] forHTTPHeaderField:@"pub_ticket"];
}else {
[client.requestSerializer setValue:nil forHTTPHeaderField:@"pub_ticket"];
}
[client.requestSerializer setValue:[NSBundle uploadLanguageText] forHTTPHeaderField:@"Accept-Language"];
[client.requestSerializer setValue:PI_App_Version forHTTPHeaderField:@"App-Version"];
}
+ (NSDictionary*)configBaseParmars:(NSDictionary * _Nullable)parmars
{
NSDictionary *defaultBasciParame = @{
@"Accept-Language":[NSBundle uploadLanguageText],
@"os" : @"iOS",
@"osVersion" : [YYUtility systemVersion],
@"netType" : ([YYUtility networkStatus] == ReachableViaWiFi) ? @2 : @1,
@"ispType" : @([YYUtility carrierIdentifier]),
@"channel" : [YYUtility getAppSource] ? : @"",
@"model" : [YYUtility modelType],
@"deviceId" : [YYUtility deviceUniqueIdentification],
@"appVersion" : [YYUtility appVersion],
@"app" : [YYUtility appName],
@"lang" : [YYUtility getLanguage],
};
if (!parmars||![parmars isKindOfClass:[NSDictionary class]]){
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:defaultBasciParame];
if(![[YYUtility getMobileCountryCode] isEqualToString:@"65535"]){
[dic setValue:[YYUtility getMobileCountryCode] forKey:@"mcc"];
}
return dic;
}
NSMutableDictionary * dic = [NSMutableDictionary dictionaryWithDictionary:parmars];
if(![[YYUtility getMobileCountryCode] isEqualToString:@"65535"]){
[dic setValue:[YYUtility getMobileCountryCode] forKey:@"mcc"];
}
[dic addEntriesFromDictionary:defaultBasciParame];
if ([[AccountInfoStorage instance] getUid].length > 0) {
[dic setValue:[[AccountInfoStorage instance] getUid]
forKey:@"pub_uid"];
}
if ([[AccountInfoStorage instance] getTicket].length > 0) {
[dic setValue:[[AccountInfoStorage instance] getTicket]
forKey:@"pub_ticket"];
}
return dic;
}
+ (void)handleNetError:(NSError *)error method:(NSString *)method
failure:(void (^)(NSInteger resCode, NSString *message))failure
{
// 别问,反正 oauth/ticket 接口要通过这种方式取错误码。
NSHTTPURLResponse *response = error.userInfo[@"com.alamofire.serialization.response.error.response"];
NSString *NETWORK_ERROR = error.description.length > 0 ? error.description : YMLocalizedString(@"HttpRequestHelper5");;
if (response && response.statusCode == 401) {
failure(response.statusCode, YMLocalizedString(@"HttpRequestHelper7"));
} else {
if (error.code == -1009 || error.code == -1001 || error.code == -1004 || error.code == -1003 || error.code == -1002 || error.code == 3840) {
failure(error.code, @"");
} else {
failure(error.code, error.localizedDescription.length > 0 ? error.localizedDescription : YMLocalizedString(@"HttpRequestHelper4"));
}
}
#if DEBUG
NSLog(@"\n%@", error);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSDictionary *allHeaders = response.allHeaderFields;
//3,
NSMutableDictionary *blockDict = [[NSMutableDictionary alloc]init];
[blockDict setObject:@(response.statusCode) forKey:@"resultCode"];
[blockDict setObject:NETWORK_ERROR forKey:@"resultDesc"];
[BSNetListenModel addHttpRsp:method header:allHeaders result:blockDict isSuccess:NO time:[NSDate getCurrentTimeWithFormat:@"yyyy-MM-dd HH:mm:ss"]];
});
#else
#endif
}
/// 增加或编辑技能卡专用接口 Post 请求参数放入到 body 里 使用 application/json 类型传递
/// @param path 请求地址
/// @param params 参数
/// @param completion 回调
+ (void)postSkillCard:(NSString *)path
params:(NSString *)params
completion:(HttpRequestHelperCompletion)completion{
if ([self checkNetworkStatusWithFailure:^{
completion(nil, -1, YMLocalizedString(@"HttpRequestHelper0"));
}]) {
return;
}
// [self configHeaders];
params = [MSParamsDecode msDecodeParams:[params.mj_JSONObject mutableCopy] ].toJSONString;
NSDictionary *baseParams = [self configBaseParmars:nil];
AFHTTPSessionManager *manager = [HttpRequestHelper requestManager];
NSString *url = [self getHostUrl];
NSString *urlPath = [NSString stringWithFormat:@"%@/%@", url ,path];
#if DEBUG
NSLog(@"\nmethod:\n%@\nparameter:\n%@", path, params);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[BSNetListenModel addHttpReq:urlPath header:manager.requestSerializer.HTTPRequestHeaders param:[params copy] time:[NSDate getCurrentTimeWithFormat:@"yyyy-MM-dd HH:mm:ss"]];
});
#else
#endif
__block NSString *requestUrl = @"";
[baseParams.allKeys enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSString *value = baseParams[obj];
requestUrl = [requestUrl stringByAppendingString:[NSString stringWithFormat:@"%@=%@&", obj, value]];
}];
urlPath = [NSString stringWithFormat:@"%@?%@", urlPath, requestUrl];
urlPath = [urlPath stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSMutableURLRequest *request = [[AFJSONRequestSerializer serializer] requestWithMethod:@"POST" URLString:urlPath parameters:baseParams error:nil];
request.timeoutInterval= [[[NSUserDefaults standardUserDefaults] valueForKey:@"timeoutInterval"] longValue];
[request setValue:@"application/json; charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
if ([[AccountInfoStorage instance] getUid].length > 0) {
[request setValue:[[AccountInfoStorage instance] getUid] forHTTPHeaderField:@"pub_uid"];
[manager.requestSerializer setValue:[[AccountInfoStorage instance] getUid] forHTTPHeaderField:@"pub_uid"];
} else {
[request setValue:nil forHTTPHeaderField:@"pub_uid"];
}
if ([[AccountInfoStorage instance] getTicket].length > 0) {
[request setValue:[[AccountInfoStorage instance] getTicket] forHTTPHeaderField:@"pub_ticket"];
[manager.requestSerializer setValue:[[AccountInfoStorage instance] getTicket] forHTTPHeaderField:@"pub_ticket"];
}else {
[request setValue:nil forHTTPHeaderField:@"pub_ticket"];
}
[request setValue:[NSBundle uploadLanguageText] forHTTPHeaderField:@"Accept-Language"];
[request setValue:PI_App_Version forHTTPHeaderField:@"App-Version"];
[manager.requestSerializer setValue:[NSBundle uploadLanguageText] forHTTPHeaderField:@"Accept-Language"];
[manager.requestSerializer setValue:PI_App_Version forHTTPHeaderField:@"App-Version"];
[request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
[[manager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
if (responseObject) {
BaseModel *baseModel = [BaseModel modelWithDictionary:responseObject];
#if DEBUG
NSLog(@"\n%@", [baseModel toJSONString]);
#else
#endif
if (baseModel.code == 200) {
#if DEBUG
NSHTTPURLResponse *urlresponse = (NSHTTPURLResponse *)response;
NSDictionary *allHeaders = urlresponse.allHeaderFields;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[BSNetListenModel addHttpRsp:urlPath header:allHeaders result:baseModel.data isSuccess:YES time:[NSDate getCurrentTimeWithFormat:@"yyyy-MM-dd HH:mm:ss"]];
});
#else
#endif
if (completion) {
completion(baseModel, 200, nil);
}
} else {
if (completion) {
completion(nil, baseModel.code, baseModel.message);
}
}
}
if (error) {
[self handleNetError:error method:path failure:^(NSInteger resCode, NSString *message) {
completion(nil, resCode, message);
}];
}
}] resume];
}
+ (BOOL)checkNetworkStatusWithFailure:(void (^)(void))failure {
if ([AFNetworkReachabilityManager sharedManager].networkReachabilityStatus == AFNetworkReachabilityStatusNotReachable) {
if (failure) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
failure();
});
}
return YES;
}
return NO;
}
@end