// // EZHttpUtil.m // EZOpenSDKDemo // // Created by 陈嘉乐 on 2021/2/26. // Copyright © 2021 hikvision. All rights reserved. // #import "EZHttpUtil.h" #import #import #import "AFNetworking.h" #define TestRequestHttpsHost @"https://test-gz.hdlcontrol.com" #pragma mark API #define API_POST_EZ_AddDevice @"/home-wisdom/platform/childAddDevice" #define API_POST_EZ_GetChildToken @"/home-wisdom/platform/childToken" #define API_POST_EZ_ChildDelDevice @"/home-wisdom/platform/childDelDevice" #define API_POST_EZ_RefreshToken @"/smart-footstone/member/oauth/login" #pragma mark APP_KEY #define APP_KEY @"HDL-HOME-APP-TEST" #define SECRET_KEY @"WeJ8TY88vbakCcnvH8G1tDUqzLWY8yss" #define TIME_OUT 15.0f @implementation EZHttpUtil #pragma mark -接口请求部分 /// sharedManager + (id)sharedManager { static dispatch_once_t once; static id instance; dispatch_once(&once, ^{ instance = [self new]; }); return instance; } /** * @since 河东获取子账号token的接口 * * @param block 回调block */ - (void)getChildToken:(void (^)(NSString *accessToken))block{ //2.设置请求参数 NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; parameters = [self GetSignRequestDictionary:parameters]; [self requestHttpsPost:API_POST_EZ_GetChildToken parameters:parameters completion:^(ResponseData *responseData) { if (block) { NSString * token = @""; if(responseData.success){ token = responseData.data[@"accessToken"]; } block(token); } }]; // return task; } /** * @since 河东添加设备的接口 * 根据设备序列号和设备验证码添加设备接口 * * @param deviceSerial 设备序列号 * @param verifyCode 设备验证码 * @param completion 回调block,error为空时表示添加成功 * */ - (void)addDeviceByHDL:(NSString *)deviceSerial verifyCode:(NSString *)verifyCode completion:(void (^)(ResponseData *responseData))completion{ //2.设置请求参数 NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; [parameters setValue:deviceSerial forKey:@"deviceSerial"]; [parameters setValue:verifyCode forKey:@"validateCode"]; parameters = [self GetSignRequestDictionary:parameters]; [self requestHttpsPost:API_POST_EZ_AddDevice parameters:parameters completion:^(ResponseData *responseData) { if (completion) { completion (responseData); } }]; // return task; } /** * @since 河东删除设备的接口 * 根据设备序列号删除设备接口 * * @param deviceSerial 设备序列号 * @param completion 回调block,error为空时表示添加成功 * */ - (void)deleteDeviceByHDL:(NSString *)deviceSerial completion:(void (^)(ResponseData *responseData))completion{ //1.设置请求参数 NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; [parameters setValue:deviceSerial forKey:@"deviceSerial"]; parameters = [self GetSignRequestDictionary:parameters]; [self requestHttpsPost:API_POST_EZ_ChildDelDevice parameters:parameters completion:^(ResponseData *responseData) { if (completion) { completion (responseData); } }]; // return task; } /// 刷新token /// @param block 结果 - (void)refreshHDLToken:(void (^)(BOOL isSuccess))block{ //1.设置请求参数 NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; [parameters setValue:GlobalKit.shareKit.hdlRefreshToken forKey:@"refreshToken"]; [parameters setValue:@"refresh_token" forKey:@"grantType"]; [parameters setValue:@"APP" forKey:@"platform"]; parameters = [self GetSignRequestDictionary:parameters]; [self requestHttpsBase:API_POST_EZ_RefreshToken parameters:parameters completion:^(ResponseData *responseData) { if (block) { if (responseData) { if(responseData.success){ [EZSDK setHDlAccessToken: [NSString stringWithFormat:@"%@%@",responseData.data[@"headerPrefix"], responseData.data[@"accessToken"]] refreshToken:responseData.data[@"refreshToken"]]; block(YES); return; } } block(NO); } }]; // return task; } #pragma mark HttpUtil /// 通用 请求服务器方法 /// @param apiPath 接口地址 /// @param parameters 请求参数 /// @param completion 请求响应参数 - (void)requestHttpsPost:(NSString *)apiPath parameters:(NSMutableDictionary *)parameters completion:(void (^)(ResponseData *responseData))completion{ [self requestHttpsBase:apiPath parameters:parameters completion:^(ResponseData *responseData) { if (completion) { if([responseData.code isEqual:@"10001"]){ //刷新token [self refreshHDLToken:^(BOOL isSuccess) { if (isSuccess) { //刷新token成功,重新请求一次 [self requestHttpsBase:apiPath parameters:parameters completion:^(ResponseData *responseData) { completion(responseData); return; }]; } }]; } completion(responseData); } }]; } /// 通用 请求服务器方法 /// @param apiPath 接口地址 /// @param parameters 请求参数 /// @param completion 请求响应参数 - (void)requestHttpsBase:(NSString *)apiPath parameters:(NSMutableDictionary *)parameters completion:(void (^)(ResponseData *responseData))completion{ //1,创建你得请求url NSString *URL = [GlobalKit shareKit].GlobalRequestHttpsHost; if([self stringIsNullOrEmpty:URL]){ URL = TestRequestHttpsHost; } URL = [NSString stringWithFormat:@"%@%@", URL, apiPath]; // NSURLSessionDataTask * task=nil; AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; AFHTTPResponseSerializer *responseSerializer = [AFHTTPResponseSerializer serializer]; manager.responseSerializer = responseSerializer; //3.request NSMutableURLRequest * request = [[AFJSONRequestSerializer serializer] requestWithMethod:@"post" URLString:URL parameters:parameters error:nil]; request.timeoutInterval = TIME_OUT; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; [request setValue:GlobalKit.shareKit.hdlAccessToken forHTTPHeaderField:@"Authorization"]; //4.dataTaskWithRequest [[manager dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { if (completion) { ResponseData *responseData = [[ResponseData alloc] init]; responseData.code = @"-1"; if(responseObject != NULL){ //4.解析拿到的响应数据 NSLog(@"%@",[[NSString alloc]initWithData:responseObject encoding:NSUTF8StringEncoding]); NSDictionary * outDic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:nil]; responseData = [[ResponseData alloc] initWithDictionary:outDic]; } if (!responseData) { responseData = [[ResponseData alloc] init]; } completion(responseData); } }]resume]; // return task; } /** * 基础服务的接口都要校验sign */ -(NSMutableDictionary *)GetSignRequestDictionary:(NSMutableDictionary *)params{ if(params == NULL){ params =[NSMutableDictionary dictionary]; } UInt64 recordTime = [[NSDate date] timeIntervalSince1970]*1000; [params setValue:APP_KEY forKey:@"appKey"]; [params setValue:[NSString stringWithFormat:@"%llu",recordTime] forKey:@"timestamp"]; //1.对KEY升序 NSArray *keyArray = [params allKeys]; NSArray *sortKeyArray = [keyArray sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { return [obj1 compare:obj2 options:NSNumericSearch]; }]; //2.2 拼接按URL键值对 NSString *newString = @""; for(NSString *key in sortKeyArray){ if(params[key] != NULL){ NSString *valueStr = params[key]; //检测当前参数是否需要参与校验 if([self IfValueNeedSign:valueStr]){ newString = [newString stringByAppendingString:[NSString stringWithFormat:@"%@=%@&", key,valueStr]]; } } } //2.3 拼接SECRET_KEY newString = [newString substringToIndex:[newString length] - 1]; newString = [newString stringByAppendingString: SECRET_KEY]; //2.4 MD5转换+转小写 if([self stringIsNullOrEmpty:newString]){ newString = @""; } NSString* signstr = [self signMD5Encrypt:newString]; [params setValue:signstr forKey:@"sign"]; return params; } /// 字符串判空 /// @param valueStr 传入判断字符 - (BOOL)stringIsNullOrEmpty:(NSString *)valueStr { if((valueStr == nil || [valueStr isKindOfClass:[NSNull class]] || valueStr.length == 0)){ return YES; }else{ return NO; } } /** MD5转换+转小写 */ - (NSString*)signMD5Encrypt:(NSString *)str { const char *cStr = [str UTF8String]; unsigned char digest[CC_MD5_DIGEST_LENGTH]; CC_MD5( cStr, strlen(cStr),digest ); NSMutableString *result = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2]; for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) [result appendFormat:@"%02x", digest[i]]; return result; } /// /// 判断当前值是否需要参与签名,保持跟云端一致 /// 空字符串不参与 /// 数组,集合,对象不参与 /// /// /// -(bool)IfValueNeedSign:(NSString *)valueStr{ if (( [self stringIsNullOrEmpty:valueStr])//判空字符 || ([[valueStr substringToIndex:1] isEqual:@"{"])//判断是否为对象 || ([[valueStr substringToIndex:1] isEqual:@"["])//判断是否为数组 ) { return false; } return true; } @end