ERequest.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. #import "ERequest.h"
  2. #import "ServerManager.h"
  3. #import "NSString+http.h"
  4. #import "NSData+http.h"
  5. #import <AFNetworking/AFNetworking.h>
  6. #define KEY_AES @"a3ca2bcd4bcda6c7" //加密
  7. @implementation ERequest
  8. + (NSDictionary*)setHeaders:(NSDictionary*)param isEncrypt:(BOOL)isEncrypt contentType:(NSString*)contentType {
  9. //当前语言
  10. NSString* localization = [[[NSUserDefaults standardUserDefaults] objectForKey:@"AppleLanguages"] firstObject];
  11. //当前时区,timestamp
  12. NSString* timezone = [self getTimezone];
  13. NSInteger interval = [[NSDate date] timeIntervalSince1970];
  14. NSString* timestamp = [NSString stringWithFormat:@"%ld", interval];
  15. //iPhone
  16. NSDictionary *infoDic = [NSBundle mainBundle].infoDictionary;
  17. NSString* iphoneAppVersion = infoDic[@"CFBundleShortVersionString"];
  18. NSString* iphoneSystemVersion = [[UIDevice currentDevice] systemVersion];
  19. NSString* iphoneModel = [[UIDevice currentDevice] name];
  20. //noncestr
  21. NSString* noncestr = [[NSString uniqueString] md5HexEncode];
  22. //token
  23. NSString* token = [self getToken];
  24. //Headers
  25. NSMutableDictionary *headers = [[NSMutableDictionary alloc] init];
  26. headers[@"Content-type"] = contentType;
  27. headers[@"Accept-Version"] = @"1.0.0";
  28. headers[@"accept-language"] = @"zh";
  29. headers[@"noncestr"] = noncestr;
  30. headers[@"Localization"] = localization;
  31. //W303B
  32. headers[@"X-Device-System"] = @"ios";
  33. headers[@"X-Device-System-Version"] = iphoneSystemVersion;
  34. headers[@"X-Device-Software-Version"] = iphoneAppVersion;
  35. headers[@"X-Device-Model"] = iphoneModel;
  36. headers[@"X-Device-Timezone"] = timezone;
  37. headers[@"X-Device-Timestamp"] = timestamp;
  38. //H210
  39. headers[@"sys"] = @"ios";
  40. headers[@"sys-no"] = iphoneSystemVersion;
  41. headers[@"timestamp"] = timestamp;
  42. headers[@"device-no"] = [ServerManager getModel];
  43. headers[@"device-model"] = [ServerManager getModel];
  44. headers[@"device-mac"] = [self getMacAddress];
  45. headers[@"device-type"] = @"3";
  46. //国内项目
  47. headers[@"X-System"] = @"IOS";
  48. headers[@"X-System-Version"] = iphoneSystemVersion;
  49. headers[@"X-Software-Version"] = iphoneAppVersion;
  50. headers[@"X-Manufacturer"] = @"Apple";
  51. headers[@"X-Time-Zone"] = timezone;
  52. headers[@"X-Timestamp"] = timestamp;
  53. headers[@"X-Request-Id"] = [NSString stringWithFormat:@"%@-%@", noncestr, timestamp];
  54. if (token && token.length > 0) {
  55. NSString* authorization = [NSString stringWithFormat:@"%@ %@", @"Bearer", token];
  56. headers[@"Authorization"] = authorization;
  57. }
  58. #ifdef SK_FUNCTION_ENCRYPT
  59. if (isEncrypt) {
  60. headers[@"token"] = token == nil ? @"" : token;
  61. if (param) {
  62. NSData* jsonData = [NSJSONSerialization dataWithJSONObject:param options:NSJSONWritingFragmentsAllowed error:nil];
  63. NSString* data = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
  64. data = [data URLEncode];
  65. NSString* sign = [NSString stringWithFormat:@"noncestr=%@&timestamp=%@&token=%@&data=%@", noncestr, timestamp, token, data];
  66. NSData *signData = [sign dataUsingEncoding:NSUTF8StringEncoding];
  67. NSString *signBase64 = [signData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
  68. sign = [signBase64 md5HexEncode];
  69. headers[@"sign"] = sign;
  70. }
  71. }
  72. #endif
  73. return headers;
  74. }
  75. + (NSData*)encryptionBody:(NSDictionary*)param isEncrypt:(BOOL)isEncrypt {
  76. #ifdef SK_FUNCTION_ENCRYPT
  77. if (isEncrypt) {
  78. NSString* key = KEY_AES;
  79. NSString* iv = KEY_AES;
  80. NSData* jsonData = [NSJSONSerialization dataWithJSONObject:param options:NSJSONWritingFragmentsAllowed error:nil];
  81. NSData *jsonDataAES = [jsonData AES128EncryptWithKey:key gIv:iv];
  82. //NSString *signBase64 = [jsonDataAES base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
  83. return [jsonDataAES base64EncodedDataWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
  84. }
  85. #endif
  86. return [NSJSONSerialization dataWithJSONObject:param options:NSJSONWritingPrettyPrinted error:nil];
  87. }
  88. + (void)httpRequest:(NSDictionary*)param
  89. path:(NSString*)path
  90. httpURL:(NSString*)httpURL
  91. httpMethod:(NSString*)httpMethod
  92. onSuccess:(void(^)(NSDictionary* result))success
  93. onFailure:(void(^)(NSError* error))failure {
  94. //如果是服务器 >= 2,不加密
  95. NSInteger type = [ServerManager getServerType];
  96. BOOL isEncrypt = type >= 2 ? NO : YES;
  97. param = [self isGET:httpMethod] ? @{} : param;
  98. httpURL = [path isStartWithString:@"?"] ? [NSString stringWithFormat:@"%@%@", httpURL, path] : [NSString stringWithFormat:@"%@/%@", httpURL, path];
  99. [self httpRequest:param httpURL:httpURL httpMethod:httpMethod httpEncrypt:isEncrypt onSuccess:success onFailure:failure];
  100. }
  101. + (void)httpRequest:(NSDictionary*)param
  102. httpURL:(NSString*)httpURL
  103. httpMethod:(NSString*)httpMethod
  104. onSuccess:(void(^)(NSDictionary* result))success
  105. onFailure:(void(^)(NSError* error))failure {
  106. //如果是服务器 >= 2,不加密
  107. NSInteger type = [ServerManager getServerType];
  108. BOOL isEncrypt = type >= 2 ? NO : YES;
  109. [self httpRequest:param httpURL:httpURL httpMethod:httpMethod httpEncrypt:isEncrypt onSuccess:success onFailure:failure];
  110. }
  111. + (void)httpRequest:(NSDictionary*)param
  112. httpURL:(NSString*)httpURL
  113. httpMethod:(NSString*)httpMethod
  114. httpEncrypt:(BOOL)isEncrypt
  115. onSuccess:(void(^)(NSDictionary* result))success
  116. onFailure:(void(^)(NSError* error))failure {
  117. NSString* contentType = @"application/json";
  118. NSDictionary* header = [self setHeaders:param isEncrypt:isEncrypt contentType:contentType];
  119. NSData *body = [self encryptionBody:param isEncrypt:isEncrypt];
  120. [self httpRequest:param httpMethod:httpMethod httpURL:httpURL httpHeader:header body:body onSuccess:success onFailure:failure];
  121. }
  122. + (void)httpRequest:(NSDictionary*)param
  123. httpURL:(NSString*)httpURL
  124. httpEncrypt:(BOOL)isEncrypt
  125. fileData:(NSData*)fileData
  126. fileName:(NSString*)fileName
  127. mimeType:(NSString*)mimeType
  128. onSuccess:(void(^)(NSDictionary* result))success
  129. onFailure:(void(^)(NSError* error))failure {
  130. NSString* httpMethod = @"POST";
  131. NSString* contentType = @"multipart/form-data";
  132. NSDictionary* header = [self setHeaders:param isEncrypt:isEncrypt contentType:contentType];
  133. if (!httpMethod || [httpMethod isEqualToString:@""])
  134. return;
  135. if (!httpURL || [httpURL isEqualToString:@""])
  136. return;
  137. NSString* allUrl = [self joinHttpDomains:httpURL];
  138. HDNormalLog(([NSString stringWithFormat:@"------->>> 【%@】%@\n header:%@\n param:%@\n", httpMethod, allUrl, header, param]));
  139. AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
  140. manager.requestSerializer = [AFJSONRequestSerializer serializer];
  141. manager.requestSerializer.timeoutInterval = 15;
  142. for (NSString* key in header.allKeys) {
  143. [manager.requestSerializer setValue:header[key] forHTTPHeaderField:key];
  144. }
  145. manager.responseSerializer = [AFJSONResponseSerializer serializer];
  146. [manager.securityPolicy setAllowInvalidCertificates:YES];
  147. [manager.securityPolicy setValidatesDomainName:NO];
  148. [manager POST:allUrl parameters:param headers:@{} constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
  149. [formData appendPartWithFileData:fileData name:@"file" fileName:fileName mimeType:mimeType];
  150. } progress:^(NSProgress * _Nonnull uploadProgress) {
  151. } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
  152. [ERequest httpCallback:httpMethod httpURL:allUrl response:task.response responseObject:responseObject error:nil onSuccess:success onFailure:failure];
  153. } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
  154. [ERequest httpCallback:httpMethod httpURL:allUrl response:task.response responseObject:nil error:error onSuccess:success onFailure:failure];
  155. }];
  156. }
  157. + (void)httpRequest:(NSDictionary*)param
  158. httpMethod:(NSString*)httpMethod
  159. httpURL:(NSString*)httpURL
  160. httpHeader:(NSDictionary*)header
  161. body:(NSData*)body
  162. onSuccess:(void(^)(NSDictionary* result))success
  163. onFailure:(void(^)(NSError* error))failure {
  164. if (!httpMethod || [httpMethod isEqualToString:@""])
  165. return;
  166. if (!httpURL || [httpURL isEqualToString:@""])
  167. return;
  168. NSString* allUrl = [self joinHttpDomains:httpURL];
  169. HDNormalLog(([NSString stringWithFormat:@"------->>> 【%@】%@\n header:%@\n param:%@\n", httpMethod, allUrl, header, param]));
  170. NSMutableURLRequest* request = [[AFHTTPRequestSerializer serializer] requestWithMethod:httpMethod URLString:allUrl parameters:param error:nil];
  171. [request setAllHTTPHeaderFields:header];
  172. [request setHTTPMethod:httpMethod];
  173. if (![self isGET:httpMethod]) {
  174. [request setHTTPBody:body];
  175. }
  176. //创建请求任务
  177. AFURLSessionManager* manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
  178. NSURLSessionDataTask *task = [manager dataTaskWithRequest:request uploadProgress:^(NSProgress * _Nonnull uploadProgress) {
  179. } downloadProgress:^(NSProgress * _Nonnull downloadProgress) {
  180. } completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
  181. [ERequest httpCallback:httpMethod httpURL:allUrl response:response responseObject:responseObject error:error onSuccess:success onFailure:failure];
  182. }];
  183. [task resume];
  184. }
  185. + (void)downloadResource:(NSString*)httpURL localPath:(NSString*)localPath callback:(void(^)(BOOL isOK))callback {
  186. NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:httpURL]];
  187. NSURLSessionDownloadTask* task = [[AFHTTPSessionManager manager] downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
  188. } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
  189. return [NSURL fileURLWithPath:localPath];
  190. } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
  191. callback(error == nil);
  192. }];
  193. [task resume];
  194. }
  195. + (void)httpCallback:(NSString*)httpMethod httpURL:(NSString*)httpURL response:(NSURLResponse*)response responseObject:(id)responseObject error:(NSError*)error onSuccess:(void(^)(NSDictionary* result))success onFailure:(void(^)(NSError* error))failure {
  196. //判断是否断网
  197. if (error && (error.code == -1009 || error.code == -1001)) {
  198. HDNormalLog(([NSString stringWithFormat:@"<<<------- 【%@】%@\n ########### %@ ########### \n", httpMethod, httpURL, error.userInfo[@"NSLocalizedDescription"]]));
  199. failure(error);
  200. } else {
  201. NSInteger statusCode = ((NSHTTPURLResponse *)response).statusCode;
  202. NSMutableDictionary* dic = [[NSMutableDictionary alloc] init];
  203. dic[@"code"] = @(statusCode);
  204. //200:请求成功
  205. if (statusCode == 200) {
  206. dic[@"data"] = responseObject;
  207. } else {
  208. [dic addEntriesFromDictionary:responseObject];
  209. }
  210. //判断是否Token过期
  211. if ([self isTokenExpiredWithResult:dic]) {
  212. [[NSNotificationCenter defaultCenter] postNotificationName:@"SK_TOKEN_EXPIRED" object:nil];
  213. }
  214. HDNormalLog(([NSString stringWithFormat:@"<<<------- 【%@】%@\n%@", httpMethod, httpURL, dic]));
  215. success(dic);
  216. }
  217. }
  218. + (void)successCallback:(NSString*)httpMethod httpURL:(NSString*)httpURL responseObject:(id)responseObject callback:(void(^)(NSDictionary *result))callback {
  219. HDNormalLog(([NSString stringWithFormat:@"<<<------- 【%@】%@\n%@", httpMethod, httpURL, responseObject]));
  220. //token过期
  221. if ([self isTokenExpiredWithResult:responseObject]) {
  222. [[NSNotificationCenter defaultCenter] postNotificationName:@"SK_TOKEN_EXPIRED" object:nil];
  223. }
  224. callback(responseObject);
  225. }
  226. + (void)failedCallback:(NSString*)httpMethod httpURL:(NSString*)httpURL responseObject:(id)responseObject error:(NSError*)error callback:(void(^)(NSError* error))callback {
  227. HDNormalLog(([NSString stringWithFormat:@"<<<------- 【%@】%@\n ########### %@ ########### \n", httpMethod, httpURL, error.userInfo[@"NSLocalizedDescription"]]));
  228. if (responseObject && [responseObject isKindOfClass:[NSDictionary class]]) {
  229. if ([self isTokenExpiredWithResult:responseObject]) {
  230. [[NSNotificationCenter defaultCenter] postNotificationName:@"SK_TOKEN_EXPIRED" object:nil];
  231. return;
  232. }
  233. }
  234. callback(error);
  235. }
  236. + (BOOL)isSuccessWithResult:(NSDictionary *)result {
  237. //200 成功
  238. NSInteger successCode = [result[@"code"] integerValue];
  239. if (successCode == 200) {
  240. return YES;
  241. }
  242. return NO;
  243. }
  244. + (BOOL)isTokenExpiredWithResult:(NSDictionary *)result {
  245. //Token过期,需要重新登录
  246. NSInteger successCode = [result[@"code"] integerValue];
  247. if (successCode == 405 || successCode == 401) {
  248. return YES;
  249. }
  250. return NO;
  251. }
  252. + (BOOL)isNeedWaitWithResult:(NSDictionary *)result {
  253. //406 中医提交数据,等待健康数据返回
  254. NSInteger successCode = [result[@"code"] integerValue];
  255. if (successCode == 406) {
  256. return YES;
  257. }
  258. return NO;
  259. }
  260. + (BOOL)isGET:(NSString*)httpMethod {
  261. return [self isStringEquel:httpMethod search:@"GET"];
  262. }
  263. + (BOOL)isStringEquel:(NSString*)value1 search:(NSString*)value2 {
  264. NSString* first = value1.trimString.uppercaseString.trimString;
  265. NSString* second = value2.trimString.uppercaseString.trimString;
  266. return [first isEqualToString:second];
  267. }
  268. + (NSString*)joinHttpDomains:(NSString*)httpURL {
  269. NSArray* info = [ServerManager getHttpDomains];
  270. NSString* url = [NSString stringWithFormat:@"%@%@", info[0], info[1]];
  271. if ([httpURL isEqualToString:@"/token/generate"]) {
  272. url = @"http://api.w303b.sikey.com.cn";
  273. }
  274. return [NSString stringWithFormat:@"%@%@",url, httpURL];
  275. }
  276. + (NSString*)joinQueryString:(NSDictionary*)dic {
  277. NSString* ret = @"";
  278. for (int i = 0; i < dic.allKeys.count; i++) {
  279. ret = [NSString stringWithFormat:@"%@%@=%@&", ret, dic.allKeys[i], dic.allValues[i]];
  280. }
  281. ret = [ret substringToIndex:ret.length - 1];
  282. return ret;
  283. }
  284. + (NSString*)getMacAddress {
  285. NSString* mac = [[NSUserDefaults standardUserDefaults] objectForKey:@"DeviceMacString"];
  286. return mac ? mac : @"";
  287. }
  288. + (NSString*)getToken {
  289. NSString* token = [[NSUserDefaults standardUserDefaults] objectForKey:@"sk_token"];
  290. return token ? token : @"";
  291. }
  292. + (NSString*)getTimezone {
  293. NSTimeInterval interval = [[NSTimeZone systemTimeZone] secondsFromGMTForDate:[NSDate date]];
  294. float timezone = interval / 3600;
  295. return [NSString stringWithFormat:@"%@%@%.1f", @"UTC", timezone > 0 ? @"+" : @"-", fabsf(timezone)];
  296. }
  297. + (NSString*)getTimezoneString {
  298. NSTimeZone* timeZone = [NSTimeZone systemTimeZone] ;///获取当前时区信息
  299. return timeZone.name;
  300. }
  301. @end