//
|
// EZHttpUtil.m
|
// EZOpenSDKDemo
|
//
|
// Created by 陈嘉乐 on 2021/2/26.
|
// Copyright © 2021 hikvision. All rights reserved.
|
//
|
|
#import "EZHttpUtil.h"
|
#import <Foundation/Foundation.h>
|
#import <CommonCrypto/CommonDigest.h>
|
#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 setValue: [NSString stringWithFormat:@"%d", [GlobalKit shareKit].hdlPlatform] forKey:@"platform"];
|
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 setValue: [NSString stringWithFormat:@"%d",[GlobalKit shareKit].hdlPlatform] forKey:@"platform"];
|
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 setValue: [NSString stringWithFormat:@"%d",[GlobalKit shareKit].hdlPlatform] forKey:@"platform"];
|
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;
|
|
|
}
|
|
/// <summary>
|
/// 判断当前值是否需要参与签名,保持跟云端一致
|
/// 空字符串不参与
|
/// 数组,集合,对象不参与
|
/// </summary>
|
/// <param name="valueStr"></param>
|
/// <returns></returns>
|
-(bool)IfValueNeedSign:(NSString *)valueStr{
|
if (( [self stringIsNullOrEmpty:valueStr])//判空字符
|
|| ([[valueStr substringToIndex:1] isEqual:@"{"])//判断是否为对象
|
|| ([[valueStr substringToIndex:1] isEqual:@"["])//判断是否为数组
|
) {
|
return false;
|
}
|
return true;
|
}
|
|
|
@end
|