MONetAPIClient.m 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. //
  2. // MONetAPIClient.m
  3. // MiMoLive
  4. //
  5. // Created by SuperC on 2023/10/12.
  6. //
  7. #import "MONetAPIClient.h"
  8. #import "MOUploadDeviceTool.h"
  9. #import "Reachability+More.h"
  10. #import "NSString+YYAdd.h"
  11. #import "NSBundle+language.h"
  12. #import <AdjustSdk/AdjustSdk.h>
  13. static MONetAPIClient *_sharedClient = nil;
  14. static dispatch_once_t onceToken;
  15. //默认的请求超时时间 (默认30秒)
  16. const static NSTimeInterval kRequestTimeout = 30.0;
  17. @interface MONetAPIClient ()
  18. @property (nonatomic, strong) ADJAttribution *attribution;
  19. @end
  20. @implementation MONetAPIClient
  21. + (MONetAPIClient *)sharedJsonClient
  22. {
  23. dispatch_once(&onceToken, ^
  24. {
  25. _sharedClient = [[MONetAPIClient alloc] initWithBaseURL:[NSURL URLWithString:kNetPath_Base]];
  26. });
  27. return _sharedClient;
  28. }
  29. + (MONetAPIClient *)jsonClientWithBaseUrl:(NSString *)baseUrl
  30. {
  31. if ([baseUrl isEqualToString:@""] ||baseUrl == nil)
  32. {
  33. _sharedClient = [[MONetAPIClient alloc] initWithBaseURL:[NSURL URLWithString:kNetPath_Base]];
  34. }
  35. else
  36. {
  37. _sharedClient = [[MONetAPIClient alloc] initWithBaseURL:[NSURL URLWithString:baseUrl]];
  38. }
  39. return _sharedClient;
  40. }
  41. + (void)attempDealloc
  42. {
  43. onceToken = 0;
  44. _sharedClient = nil;
  45. MOLogV(@"setHttpHeaderData:::: dealloc");
  46. }
  47. - (id)initWithBaseURL:(NSURL *)url
  48. {
  49. self = [super initWithBaseURL:url];
  50. if (!self)
  51. {
  52. return nil;
  53. }
  54. self.responseSerializer = [AFJSONResponseSerializer serializer];
  55. self.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/plain", @"text/javascript", @"text/json", @"text/html",nil];
  56. self.requestSerializer = [AFJSONRequestSerializer serializer];
  57. self.requestSerializer.timeoutInterval = kRequestTimeout;
  58. //证书校验模式为None
  59. AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
  60. securityPolicy.allowInvalidCertificates = YES;
  61. securityPolicy.validatesDomainName = NO;
  62. self.securityPolicy = securityPolicy;
  63. WEAKSELF
  64. [Adjust attributionWithCompletionHandler:^(ADJAttribution * _Nullable attribution) {
  65. weakSelf.attribution = attribution;
  66. }];
  67. return self;
  68. }
  69. - (void)requestJsonDataWithPath:(NSString *)aPath withParams:(NSDictionary*)params withMethodType:(int)networkMethodInt andBlock:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))block
  70. {
  71. [self requestJsonDataWithPath:aPath withParams:params withMethodType:networkMethodInt requestTimeout:kRequestTimeout andBlock:block];
  72. }
  73. - (void)requestJsonDataWithPath:(NSString *)aPath withParams:(NSDictionary*)params withMethodType:(int)networkMethodInt requestTimeout:(NSTimeInterval)requestTimeout andBlock:(void (^)(id data, NSError *error))block{
  74. //判断请求超时时间是否符合要求
  75. if (fabs(requestTimeout - self.requestSerializer.timeoutInterval) > 0.1)
  76. {
  77. self.requestSerializer.timeoutInterval = requestTimeout;
  78. }
  79. //log请求数据
  80. //增加域名信息打印,方便排查问题
  81. MOLogV(@"\n===========request===========\n%@%@:\n%@",self.baseURL.absoluteString,aPath,params);
  82. [self setHttpHeaderDataWith:params.modelToJSONString];
  83. //发起请求
  84. switch (networkMethodInt)
  85. {
  86. case Get:
  87. {
  88. [self GET:aPath parameters:params headers:nil progress:^(NSProgress * _Nonnull downloadProgress)
  89. {
  90. }
  91. success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject)
  92. {
  93. //添加接口访问时长计算
  94. NSTimeInterval apiEndTime = [[NSDate date] timeIntervalSince1970];
  95. NSUInteger endTimestamp = apiEndTime * 1000;
  96. MOLogV(@"=====> %@ response:%@",aPath,responseObject);
  97. id error = [self handleResponse:responseObject];
  98. if (error)
  99. {
  100. block(nil, error);
  101. }
  102. else
  103. {
  104. block(responseObject, nil);
  105. }
  106. }
  107. failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error)
  108. {
  109. block(nil, error);
  110. }];
  111. break;
  112. }
  113. case Post:
  114. {
  115. [self POST:aPath parameters:params headers:nil progress:^(NSProgress * _Nonnull uploadProgress)
  116. {
  117. }
  118. success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject)
  119. {
  120. MOLogV(@"=====> %@ response:%@",aPath,responseObject);
  121. id error = [self handleResponse:responseObject];
  122. if (error)
  123. {
  124. block(nil, error);
  125. }
  126. else
  127. {
  128. block(responseObject, nil);
  129. }
  130. }
  131. failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error)
  132. {
  133. block(nil, error);
  134. }];
  135. break;
  136. }
  137. case Put:
  138. {
  139. [self PUT:aPath parameters:params headers:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject)
  140. {
  141. MOLogV(@"=====> %@ response:%@",aPath,responseObject);
  142. id error = [self handleResponse:responseObject];
  143. if (error)
  144. {
  145. block(nil, error);
  146. }
  147. else
  148. {
  149. block(responseObject, nil);
  150. }
  151. }
  152. failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error)
  153. {
  154. block(nil, error);
  155. }];
  156. break;
  157. }
  158. case Delete:
  159. {
  160. [self DELETE:aPath parameters:params headers:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject)
  161. {
  162. MOLogV(@"=====> %@ response:%@",aPath,responseObject);
  163. id error = [self handleResponse:responseObject];
  164. if (error)
  165. {
  166. block(nil, error);
  167. }
  168. else
  169. {
  170. block(responseObject, nil);
  171. }
  172. }
  173. failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error)
  174. {
  175. block(nil, error);
  176. }];
  177. break;
  178. }
  179. default:
  180. break;
  181. }
  182. }
  183. - (NSURLSessionDataTask *)requestJsonDataWithPath:(NSString *)aPath withData:(NSData *)data withType:(NSString *)type withParams:(NSDictionary *)params withMethodType:(int)networkMethodInt withProgressHandler:(void (^)(NSProgress *))progressHandler andBlock:(void (^)(id, NSError *))block
  184. {
  185. self.requestSerializer.timeoutInterval = 600;
  186. NSURLSessionDataTask *task = nil;
  187. switch (networkMethodInt)
  188. {
  189. case Post:
  190. {
  191. //DDLogDebug(@"-----> request chatserver[post] %@\n params:%@\n headers:%@",aPath,params,self.requestSerializer.HTTPRequestHeaders);
  192. task = [self POST:aPath parameters:params headers:nil constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData)
  193. {
  194. if (data)
  195. {
  196. if ([type hasPrefix:@"image"] || [type hasPrefix:@"f_image"])
  197. {
  198. [formData appendPartWithFileData:data name:@"file" fileName:[NSString stringWithFormat:@"%@.%@",[NSString stringWithFormat:@"%lu",(unsigned long)[data hash]], [type stringByReplacingOccurrencesOfString:@"image/" withString:@""]] mimeType:type];
  199. }
  200. }
  201. }
  202. progress:^(NSProgress * _Nonnull uploadProgress)
  203. {
  204. progressHandler?progressHandler(uploadProgress):nil;
  205. }
  206. success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject)
  207. {
  208. id error = [self handleResponse:responseObject];
  209. if (error)
  210. {
  211. block(nil, error);
  212. }
  213. else
  214. {
  215. block(responseObject, nil);
  216. }
  217. }
  218. failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error)
  219. {
  220. block(nil, error);
  221. }];
  222. break;
  223. }
  224. }
  225. return task;
  226. }
  227. #pragma mark -- 错误码处理 --
  228. - (id)handleResponse:(id)responseJSON
  229. {
  230. NSError *error = nil;
  231. if ([responseJSON isKindOfClass:[NSArray class]])
  232. {
  233. return error;
  234. }
  235. //code为非0值时,表示有错
  236. NSNumber *resultCode = [responseJSON valueForKeyPath:@"ErrorCode"];
  237. if (resultCode.intValue!=0)
  238. {
  239. error = [NSError errorWithDomain:kNetPath_Base code:resultCode.intValue userInfo:responseJSON];
  240. return error;
  241. }
  242. return error;
  243. }
  244. - (void)setHttpHeaderDataWith:(NSString *)bodyStr{
  245. int64_t timestamp = round([[NSDate date] timeIntervalSince1970]*1000);
  246. //Adjust
  247. // ADJAttribution *adjInfo = [Adjust attribution];
  248. //生成一个随机的10位字符串
  249. NSString *randomString = [self getIDRandom];
  250. NSString *timeString = [NSString stringWithFormat:@"%lld",timestamp];
  251. NSString *idString = [NSString stringWithFormat:@"%@-%@",randomString,timeString];
  252. //id
  253. [self.requestSerializer setValue:idString forHTTPHeaderField:@"id"];
  254. NSString *signStr = [self addNewStringWith:@"" AndNeedStr:idString];
  255. //udid
  256. NSString *udid = [MOUploadDeviceTool shareTool].adid;
  257. if (udid.length > 0) {
  258. [self.requestSerializer setValue:udid forHTTPHeaderField:@"udid"];
  259. }
  260. signStr = [self addNewStringWith:signStr AndNeedStr:udid];
  261. //app
  262. NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
  263. if(bundleIdentifier.length > 0){
  264. [self.requestSerializer setValue:bundleIdentifier forHTTPHeaderField:@"app"];
  265. }
  266. signStr = [self addNewStringWith:signStr AndNeedStr:bundleIdentifier];
  267. //device
  268. UIDevice *device = [UIDevice currentDevice];
  269. NSString *deviceModelString = device.model;
  270. if(deviceModelString.length > 0){
  271. [self.requestSerializer setValue:deviceModelString forHTTPHeaderField:@"device"];
  272. }
  273. signStr = [self addNewStringWith:signStr AndNeedStr:deviceModelString];
  274. //plaform 2 = Apple
  275. [self.requestSerializer setValue:@"2" forHTTPHeaderField:@"platform"];
  276. signStr = [self addNewStringWith:signStr AndNeedStr:@"2"];
  277. //channel
  278. __block NSString *channelStr = @"apple";
  279. if (self.attribution.network.length > 0) {
  280. channelStr = [NSString stringWithFormat:@"%@/%@",channelStr,self.attribution.network];
  281. }
  282. if (self.attribution.campaign.length > 0) {
  283. channelStr = [NSString stringWithFormat:@"%@/%@",channelStr,self.attribution.campaign];
  284. }
  285. [self.requestSerializer setValue:channelStr forHTTPHeaderField:@"channel"];
  286. signStr = [self addNewStringWith:signStr AndNeedStr:channelStr];
  287. // if(adjInfo){
  288. // if(adjInfo.network.length > 0){
  289. // channelStr = [NSString stringWithFormat:@"%@/%@",channelStr,adjInfo.network];
  290. // }
  291. //
  292. // if(adjInfo.campaign.length > 0){
  293. // channelStr = [NSString stringWithFormat:@"%@/%@",channelStr,adjInfo.campaign];
  294. // }
  295. // }
  296. //api
  297. [self.requestSerializer setValue:@"1" forHTTPHeaderField:@"api"];
  298. signStr = [self addNewStringWith:signStr AndNeedStr:@"1"];
  299. //version
  300. NSString *versionString = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
  301. [self.requestSerializer setValue:versionString forHTTPHeaderField:@"version"];
  302. signStr = [self addNewStringWith:signStr AndNeedStr:versionString];
  303. //MARK: network
  304. //network
  305. NSString *networkString = [Reachability netName];
  306. [self.requestSerializer setValue:networkString forHTTPHeaderField:@"network"];
  307. signStr = [self addNewStringWith:signStr AndNeedStr:networkString];
  308. //time
  309. [self.requestSerializer setValue:timeString forHTTPHeaderField:@"time"];
  310. signStr = [self addNewStringWith:signStr AndNeedStr:timeString];
  311. // //测试环境, 可以跳过签名验证
  312. // if (kAPP_Environment == 2){
  313. // [self.requestSerializer setValue:@"a66888" forHTTPHeaderField:@"test-skip"];
  314. // }
  315. //token
  316. NSString *tokenString = GetToken;
  317. if(tokenString.length > 0)
  318. {
  319. [self.requestSerializer setValue:tokenString forHTTPHeaderField:@"token"];
  320. }
  321. else{
  322. tokenString = @"";
  323. [self.requestSerializer setValue:tokenString forHTTPHeaderField:@"token"];
  324. }
  325. signStr = [self addNewStringWith:signStr AndNeedStr:tokenString];
  326. signStr = [self addNewStringWith:signStr AndNeedStr:@"abc|abc|edg|9527|1234"];
  327. signStr = [self addNewStringWith:signStr AndNeedStr:bodyStr];
  328. NSString *md5Str = [signStr md5String];
  329. [self.requestSerializer setValue:md5Str forHTTPHeaderField:@"sign"];
  330. NSString *currentLanguage = [NSBundle currentLanguage];
  331. [self.requestSerializer setValue:currentLanguage forHTTPHeaderField:@"Accept-Language"];
  332. }
  333. - (NSString *)addNewStringWith:(NSString *)oldStr AndNeedStr:(NSString *)str{
  334. if(!str || str.length == 0){
  335. str = @"";
  336. }
  337. oldStr = [oldStr stringByAppendingString:str];
  338. return oldStr;
  339. }
  340. - (NSString *)getIDRandom{
  341. // 声明一个字符数组,包含所有可能的字符
  342. NSString *characters = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  343. // 初始化一个空字符串,用来存储随机生成的字符串
  344. NSString *randomString = [[NSString alloc] init];
  345. // 生成10个随机的字符并拼接到 randomString 中
  346. for (int i = 0; i < 10; i++) {
  347. int randomIndex = arc4random() % [characters length];
  348. randomString = [randomString stringByAppendingString: [characters substringWithRange: NSMakeRange(randomIndex, 1)]];
  349. }
  350. // 输出结果
  351. return randomString;
  352. }
  353. @end