// // APIManager.m // LekangGuard // // Created by ecell on 2022/10/10. // #import "APIManager.h" #import "APRequestSerializer.h" #import "AppDelegate.h" //#ifdef DEBUG //测试环境 NSString *const dHostUrl = @"http://lb-mi23utxo-em1lnrk4gizs2pu8.clb.ap-nanjing.tencentclb.com:8822"; //#else ////正式环境 //NSString *const dHostUrl = @"http://lb-mi23utxo-em1lnrk4gizs2pu8.clb.ap-nanjing.tencentclb.com:8822"; //#endif NSString *const sRelogin = @"sRelogin"; NSString *const sLoginKey = @"sLoginModel"; NSString *const sDeviceKey = @"sDeviceModel"; NSString *const sUserKey = @"sUserModel"; NSString *const sDeviceListKey = @"sDeviceListKey"; NSString *const kErrorDomain = @"kErrorDomain"; NSInteger const kErrorException = 500; @implementation APIManager + (instancetype)sharedManager { static dispatch_once_t onceToken; static APIManager *apitance; dispatch_once(&onceToken, ^{ apitance = [[APIManager alloc] init]; apitance.cache = [YYCache cacheWithName:@"hx_cache_data"]; if ([apitance.cache containsObjectForKey:sLoginKey]) { id object = [apitance.cache objectForKey:sLoginKey]; if ([object isKindOfClass:LoginModel.class]) { apitance.loginModel = object; } } if ([apitance.cache containsObjectForKey:sDeviceKey]) { id object = [apitance.cache objectForKey:sDeviceKey]; if ([object isKindOfClass:DeviceModel.class]) { apitance.deviceModel = object; } } if ([apitance.cache containsObjectForKey:sUserKey]) { id object = [apitance.cache objectForKey:sUserKey]; if ([object isKindOfClass:MyUserMsgModel.class]) { apitance.userModel = object; } } if ([apitance.cache containsObjectForKey:sDeviceListKey]) { id object = [apitance.cache objectForKey:sDeviceListKey]; if ([object isKindOfClass:NSMutableArray.class]) { apitance.deviceList = object; } } }); return apitance; } /// 清除数据 - (void)clearUserInfo { if ([self.cache containsObjectForKey:sLoginKey]) { [self.cache removeObjectForKey:sLoginKey]; self.loginModel.isLogin = NO; self.loginModel = nil; self.laloModel = nil; } if ([self.cache containsObjectForKey:sDeviceKey]) { [self.cache removeObjectForKey:sDeviceKey]; self.deviceModel = nil; } if ([self.cache containsObjectForKey:sUserKey]) { [self.cache removeObjectForKey:sUserKey]; self.userModel = nil; } NSLog(@"%@",self.loginModel); } /// 解绑清除设备数据 - (void)cleardeviceInfo { if ([self.cache containsObjectForKey:sDeviceKey]) { [self.cache removeObjectForKey:sDeviceKey]; self.deviceModel = nil; self.laloModel = nil; } NSLog(@"%@",self.loginModel); } #pragma mark- POST请求 /// POST请求 /// @param URL 接口名 /// @param parameters 接口传参 /// @param isJson 是否是json /// @param resultClass 返回数据类型模型 - (RACSignal *)APPOST:(NSString *)URL parameters:(id )parameters isJson:(BOOL)isJson resultClass:(Class __nullable)resultClass { if ([resultClass isSubclassOfClass:LoginModel.class]) { return [[self APHTTPWithMethod:MSRequestMethodPOST URL:URL isJson:isJson parameters:parameters resultClass:resultClass] doNext:^(LoginModel *model) { model.isLogin = YES; self.loginModel = model; [self.cache setObject:model forKey:sLoginKey]; }]; } else return [self APHTTPWithMethod:MSRequestMethodPOST URL:URL isJson:isJson parameters:parameters resultClass:resultClass]; } #pragma mark- GET请求 /// GET请求 /// @param URL 接口名 /// @param parameters 接口传参 /// @param resultClass 返回数据类型模型 - (RACSignal *)APGET:(NSString *)URL parameters:(NSDictionary *)parameters resultClass:(Class __nullable)resultClass { if ([resultClass isSubclassOfClass:LatestLocationModel.class]) { return [[self APHTTPWithMethod:MSRequestMethodGET URL:URL isJson:NO parameters:parameters resultClass:resultClass] doNext:^(LatestLocationModel *model) { self.laloModel = model; }]; } else if ([resultClass isSubclassOfClass:MyUserMsgModel.class]) { return [[self APHTTPWithMethod:MSRequestMethodGET URL:URL isJson:NO parameters:parameters resultClass:resultClass] doNext:^(MyUserMsgModel *model) { self.userModel = model; [self.cache setObject:model forKey:sUserKey]; }]; } else if ([URL isEqualToString:BindDevice_URL]) { return [[self APHTTPWithMethod:MSRequestMethodGET URL:URL isJson:NO parameters:parameters resultClass:resultClass] doNext:^(NSArray *arr) { [self.deviceList removeAllObjects]; NSMutableArray *devArr = [NSMutableArray new]; for (NSDictionary *dic in arr) { DeviceModel *model = [DeviceModel yy_modelWithJSON:dic]; [devArr addObject:model]; } self.deviceList = devArr; [self.cache setObject:devArr forKey:sDeviceListKey]; }]; } else return [self APHTTPWithMethod:MSRequestMethodGET URL:URL isJson:NO parameters:parameters resultClass:resultClass]; } #pragma mark- DELETE请求 /// DELETE请求 /// @param URL 接口名 /// @param parameters 接口传参 /// @param resultClass 返回数据类型模型 - (RACSignal *)APDELETE:(NSString *)URL parameters:(NSDictionary *)parameters resultClass:(Class __nullable)resultClass { return [self APHTTPWithMethod:MSRequestMethodDELETE URL:URL isJson:NO parameters:parameters resultClass:resultClass]; } #pragma mark- 自定义请求方式 /// 自定义请求方式 /// @param method 请求类型 /// @param URL 接口名称 /// @param isJson 是否是json /// @param parameters 接口传参 /// @param resultClass 返回数据类型模型 - (RACSignal *)APHTTPWithMethod:(MSRequestMethod)method URL:(NSString *)URL isJson:(BOOL)isJson parameters:(id)parameters resultClass:(Class)resultClass { [MSNetwork openLog]; [MSNetwork setBaseURL:dHostUrl]; [MSNetwork setRequestSerializer: MSRequestSerializerHTTP]; if (isJson) { [MSNetwork setRequestSerializer: MSRequestSerializerJSON]; } [MSNetwork setHeader:[self setHttpHeader]]; // NSString * url = [[NSString stringWithFormat:@"%@",URL] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; RACSignal *requestSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) { [MSNetwork HTTPWithMethod:method url:[NSString stringWithFormat:@"%@",URL] parameters:parameters headers:nil cachePolicy:MSCachePolicyOnlyNetNoCache success:^(id _Nonnull responseObject) { [subscriber sendNext:responseObject]; [subscriber sendCompleted]; } failure:^(NSError * _Nonnull error) { [subscriber sendError:error]; }]; return [RACDisposable disposableWithBlock:^{ NSLog(@"6 订阅流程结束,可清理资源"); }]; }]; void (^extraHandlerSingal)(id value) = ^(RACTuple * value) { }; return [[[requestSignal catch:^RACSignal *(NSError *error) { NSData *data = error.userInfo[@"com.alamofire.serialization.response.error.data"]; if (data) { NSLog(@"error = %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); } [UICommon HidenLoading]; return [RACSignal error:error]; }] flattenMap:^RACSignal *(id _Nullable data) { return [RACSignal createSignal:^RACDisposable *(id subscriber) { [UICommon HidenLoading]; //@strongify(self); NSString *status = F(@"%@", data[@"code"]); id resultObj = data[@"data"]; if ([status isKindOfClass:[NSString class]] && [status isEqualToString:@"200"]) { //如果传递的class是PYBaseModel的子类,才解析成对象,否则不做处理 if (resultObj && resultClass && [resultClass isSubclassOfClass:BaseModel.class]) { if ([resultObj isKindOfClass:[NSArray class]]) { resultObj = [NSArray yy_modelArrayWithClass:resultClass json:resultObj]; } // else if ([resultObj isKindOfClass:[NSDictionary class]]) // { // resultObj = [NSDictionary yy_modelDictionaryWithClass:resultClass json:resultObj]; // } else { resultObj = [resultClass yy_modelWithJSON:resultObj]; } } else { //未传递classl对象,数据不解析,有些接口直接返回基础类型,这里不需要转换 if ([resultObj isKindOfClass:NSNull.class]) { resultObj = nil; } } if (resultObj) { //[self.cache setObject:resultObj forKey:[self cacheKeyWithParameters:parameters apiName:url]]; } // NSLog(@"resultObj = %@",resultObj); [subscriber sendNext:resultObj]; } else { //有网络 NSString *content = data[@"msg"]; NSString *message = [content isNotBlank] ? content : @""; NSDictionary *userInfo = @{NSLocalizedDescriptionKey : message,@"detail":status}; //其他错误 NSError *error = [NSError errorWithDomain:kErrorDomain code:kErrorException userInfo:userInfo]; [subscriber sendError:error]; } [subscriber sendCompleted]; if ([status isEqualToString:@"401"]) { [MSNetwork cancelAllRequest]; [[NSNotificationCenter defaultCenter] postNotificationName:sRelogin object:nil]; } // else if ([status isEqualToString:@"401"]) // { // [MSNetwork cancelAllRequest]; // [[NSNotificationCenter defaultCenter] postNotificationName:hRelogin object:nil]; // } return nil; }]; }] doNext:extraHandlerSingal]; } /// 下载文件 /// @param url url /// @param path 下载目标路径 - (RACSignal *)downloadWithURL:(NSString *)url filePath:(NSString *)path { [MSNetwork openLog]; RACSignal *requestSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) { [MSNetwork downloadWithURL:url fileDir:path progress:^(NSProgress * _Nonnull progress) { } success:^(NSString * _Nonnull path) { [UICommon HidenLoading]; [subscriber sendNext:path]; [subscriber sendCompleted]; } failure:^(NSError * _Nonnull error) { [subscriber sendError:error]; [UICommon HidenLoading]; }]; return [RACDisposable disposableWithBlock:^{ NSLog(@"6 订阅流程结束,可清理资源"); }]; }]; void (^extraHandlerSingal)(id value) = ^(RACTuple * value) { }; return [[[requestSignal catch:^RACSignal *(NSError *error) { NSData *data = error.userInfo[@"com.alamofire.serialization.response.error.data"]; if (data) { NSLog(@"error = %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); } [UICommon HidenLoading]; return [RACSignal error:error]; }] flattenMap:^RACSignal *(id _Nullable data) { return [RACSignal createSignal:^RACDisposable *(id subscriber) { [UICommon HidenLoading]; [subscriber sendNext:data]; return nil; }]; }] doNext:extraHandlerSingal]; } /// 上传图片文件 /// @param url 接口名 /// @param parameters 参数 /// @param images 图片数组 - (RACSignal *)uploadImageWithURL:(NSString *)url parameters:(NSDictionary *)parameters images:(NSArray * __nullable)images { [MSNetwork openLog]; RACSignal *requestSignal; requestSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) { [MSNetwork uploadImageURL:[NSString stringWithFormat:@"%@%@",dHostUrl,url] parameters:parameters headers:[self setHttpHeader] images:images name:@"file" fileName:@"image" imageScale:0.3 imageType:@"png" progress:^(NSProgress * _Nonnull progress) { } success:^(id _Nonnull responseObject) { [UICommon HidenLoading]; [subscriber sendNext:responseObject]; [subscriber sendCompleted]; } failure:^(NSError * _Nonnull error) { [UICommon HidenLoading]; [UICommon MessageErrorText:F(@"上传错误:%@",error)]; }]; return [RACDisposable disposableWithBlock:^{ NSLog(@"6 订阅流程结束,可清理资源"); }]; }]; void (^extraHandlerSingal)(id value) = ^(RACTuple * value) { }; return [[[requestSignal catch:^RACSignal *(NSError *error) { NSData *data = error.userInfo[@"com.alamofire.serialization.response.error.data"]; if (data) { NSLog(@"error = %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); } [UICommon HidenLoading]; return [RACSignal error:error]; }] flattenMap:^RACSignal *(id _Nullable data) { return [RACSignal createSignal:^RACDisposable *(id subscriber) { [UICommon HidenLoading]; //@strongify(self); NSString *status = F(@"%@", data[@"code"]); id resultObj = data[@"data"]; if ([status isKindOfClass:[NSString class]] && [status isEqualToString:@"200"]) { [subscriber sendNext:resultObj]; } else { //有网络 NSString *content = data[@"msg"]; NSString *message = [content isNotBlank] ? content : @""; NSDictionary *userInfo = @{NSLocalizedDescriptionKey : message,@"detail":status}; //其他错误 NSError *error = [NSError errorWithDomain:kErrorDomain code:kErrorException userInfo:userInfo]; [subscriber sendError:error]; } [subscriber sendCompleted]; if ([status isEqualToString:@"401"]) { [[NSNotificationCenter defaultCenter] postNotificationName:sRelogin object:nil]; } return nil; }]; }] doNext:extraHandlerSingal]; } /// 上传文件 /// @param url 接口名 /// @param parameters 参数 /// @param filePath 文件路径 /// @param fileData 文件 - (RACSignal *)uploadFileWithURL:(NSString *)url parameters:(NSDictionary *)parameters filePath:(NSString *)filePath fileData:(NSData *)fileData { [MSNetwork openLog]; RACSignal *requestSignal; if (filePath.length > 0) { requestSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) { [MSNetwork uploadFileWithURL:[NSString stringWithFormat:@"%@%@",dHostUrl,url] parameters:parameters headers:[self setHttpHeader] name:@"file" filePath:filePath progress:^(NSProgress * _Nonnull progress) { } success:^(id _Nonnull responseObject) { [UICommon HidenLoading]; [subscriber sendNext:responseObject]; [subscriber sendCompleted]; } failure:^(NSError * _Nonnull error) { [UICommon HidenLoading]; [UICommon MessageErrorText:F(@"上传错误:%@",error)]; }]; return [RACDisposable disposableWithBlock:^{ NSLog(@"6 订阅流程结束,可清理资源"); }]; }]; } // else // { // requestSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) { // [MSNetwork uploadImageURL:[NSString stringWithFormat:@"%@%@",dHostUrl,url] parameters:parameters headers:[self setHttpHeader] images:@[] name:@"file" fileName:@"image" imageScale:0.5 imageType:@"png" progress:^(NSProgress * _Nonnull progress) { // // } success:^(id _Nonnull responseObject) { // // } failure:^(NSError * _Nonnull error) { // // }]; // [MSNetwork uploadFileDataWithURL:[NSString stringWithFormat:@"%@%@",dHostUrl,url] parameters:parameters headers:[self setHttpHeader] name:@"file" fileData:fileData progress:^(NSProgress * _Nonnull progress) { // // } success:^(id _Nonnull responseObject) { // [UICommon HidenLoading]; // [subscriber sendNext:responseObject]; // [subscriber sendCompleted]; // } failure:^(NSError * _Nonnull error) { // [UICommon HidenLoading]; // [UICommon MessageErrorText:F(@"上传错误:%@",error)]; // // }]; // // return [RACDisposable disposableWithBlock:^{ // NSLog(@"6 订阅流程结束,可清理资源"); // }]; // // }]; // } void (^extraHandlerSingal)(id value) = ^(RACTuple * value) { }; return [[[requestSignal catch:^RACSignal *(NSError *error) { NSData *data = error.userInfo[@"com.alamofire.serialization.response.error.data"]; if (data) { NSLog(@"error = %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); } [UICommon HidenLoading]; return [RACSignal error:error]; }] flattenMap:^RACSignal *(id _Nullable data) { return [RACSignal createSignal:^RACDisposable *(id subscriber) { [UICommon HidenLoading]; //@strongify(self); NSString *status = F(@"%@", data[@"code"]); id resultObj = data[@"data"]; if ([status isKindOfClass:[NSString class]] && [status isEqualToString:@"200"]) { [subscriber sendNext:resultObj]; } else { //有网络 NSString *content = data[@"msg"]; NSString *message = [content isNotBlank] ? content : @""; NSDictionary *userInfo = @{NSLocalizedDescriptionKey : message,@"detail":status}; //其他错误 NSError *error = [NSError errorWithDomain:kErrorDomain code:kErrorException userInfo:userInfo]; [subscriber sendError:error]; } [subscriber sendCompleted]; if ([status isEqualToString:@"401"]) { [[NSNotificationCenter defaultCenter] postNotificationName:sRelogin object:nil]; } return nil; }]; }] doNext:extraHandlerSingal]; } #pragma mark- 设置网络请求头部视图 /// 设置网络请求头部视图 - (NSMutableDictionary *)setHttpHeader { NSMutableDictionary *header = [NSMutableDictionary dictionary]; if (self.loginModel && [self.loginModel.Authorization isNotBlank]) { [header setValue:self.loginModel.Authorization forKey:@"Authorization"]; /// 当前登陆的用户ID [header setValue:self.loginModel.openid forKey:@"openid"]; } else { [header setValue:@"0" forKey:@"Authorization"]; /// 当前登陆的用户ID [header setValue:@"0" forKey:@"openid"]; } /// 请求时间 long long timestamp = [[NSDate date] timeIntervalSince1970] * 1000; [header setValue:F(@"%lld", timestamp) forKey:@"timestamp"]; /// bundleId NSString *bundleId = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"]; [header setValue:bundleId forKey:@"package"]; /// 设备id [header setObject:[UIDevice currentDevice].identifierForVendor.UUIDString forKey:@"deviceId"]; /// 设备类型 [header setValue:@"MOBILE" forKey:@"deviceType"]; /// 设备型号 [header setValue:[[UIDevice currentDevice] model] forKey:@"deviceModel"]; /// 系统版本 [header setValue:[UIDevice currentDevice].systemVersion forKey:@"osVersion"]; /// 系统类型 [header setValue:@"IOS" forKey:@"osType"]; /// 必传 [header setValue:@"APP" forKey:@"loginChannel"]; /// 版本 NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; [header setValue:version forKey:@"appVersion"]; /// 发布渠道 #ifdef DEBUG [header setValue:@"develop" forKey:@"version"]; #else [header setValue:@"produce" forKey:@"version"]; #endif NSString *deviceTokens = [UserDefaults objectForKey:DeviceTokenKey]; /// APNS Token [header setValue:STRINGHASVALUE(deviceTokens) ? deviceTokens : @"" forKey:@"deviceToken"]; NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0]; NSArray *array = [language componentsSeparatedByString:@"-"]; NSString *currentLanguage = array[0]; NSString *current = [currentLanguage isEqualToString:@"en"] ? F(@"%@_US", currentLanguage) : F(@"%@_CN", currentLanguage); [header setValue:current forKey:@"Accept-Language"]; return header; } /// 使用body传数据 - (RACSignal *)PostBodyWithApi:(NSString *)api json:(id)json { RACSignal *requestSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) { NSString*requestUrl = api; AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; NSMutableURLRequest *request = [self GetRequest:requestUrl]; // 设置body NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding]; [request setHTTPBody:data]; AFHTTPResponseSerializer *responseSerializer = [AFHTTPResponseSerializer serializer]; responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",nil]; manager.responseSerializer = responseSerializer; NSLog(@"\r头部请求参数:%@",request); [[manager dataTaskWithRequest:request uploadProgress:^(NSProgress * _Nonnull uploadProgress) { } downloadProgress:^(NSProgress * _Nonnull downloadProgress) { } completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { if (error) { [subscriber sendError:error]; } else { [subscriber sendNext:responseObject]; [subscriber sendCompleted]; } }] resume]; return [RACDisposable disposableWithBlock:^{ NSLog(@"6 订阅流程结束,可清理资源"); }]; }]; void (^extraHandlerSingal)(id value) = ^(RACTuple * value) { }; return [[[requestSignal catch:^RACSignal *(NSError *error) { NSData *data = error.userInfo[@"com.alamofire.serialization.response.error.data"]; if (data) { NSLog(@"error = %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); } [UICommon HidenLoading]; return [RACSignal error:error]; }] flattenMap:^RACSignal *(id _Nullable data) { return [RACSignal createSignal:^RACDisposable *(id subscriber) { [UICommon HidenLoading]; NSDictionary *dictFromData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil]; NSLog(@"--->%@",dictFromData); //@strongify(self); NSString *status = F(@"%@", dictFromData[@"code"]); id resultObj = dictFromData[@"data"]; if ([status isKindOfClass:[NSString class]] && [status isEqualToString:@"200"]) { [subscriber sendNext:resultObj]; } else { //有网络 NSString *content = dictFromData[@"msg"]; NSString *message = [content isNotBlank] ? content : @""; NSDictionary *userInfo = @{NSLocalizedDescriptionKey : message,@"code":status}; //其他错误 NSError *error = [NSError errorWithDomain:kErrorDomain code:kErrorException userInfo:userInfo]; [subscriber sendError:error]; } [subscriber sendCompleted]; if ([status isEqualToString:@"401"]) { [[NSNotificationCenter defaultCenter] postNotificationName:sRelogin object:nil]; } return nil; }]; }] doNext:extraHandlerSingal]; } - (NSMutableURLRequest *)GetRequest:(NSString *)URL { NSString *reURL = F(@"%@%@", dHostUrl,URL); NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:reURL parameters:nil error:nil]; request.timeoutInterval = 30; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; if (self.loginModel && [self.loginModel.Authorization isNotBlank]) { [request setValue:self.loginModel.Authorization forHTTPHeaderField:@"Authorization"]; /// 当前登陆的用户ID [request setValue:self.loginModel.openid forHTTPHeaderField:@"openid"]; } else { [request setValue:@"0" forHTTPHeaderField:@"Authorization"]; /// 当前登陆的用户ID [request setValue:@"0" forHTTPHeaderField:@"openid"]; } /// 请求时间 long long timestamp = [[NSDate date] timeIntervalSince1970] * 1000; [request setValue:F(@"%lld", timestamp) forHTTPHeaderField:@"timestamp"]; /// bundleId NSString *bundleId = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"]; [request setValue:bundleId forHTTPHeaderField:@"package"]; /// 设备id [request setValue:[UIDevice currentDevice].identifierForVendor.UUIDString forHTTPHeaderField:@"deviceId"]; /// 设备类型 [request setValue:@"MOBILE" forHTTPHeaderField:@"deviceType"]; /// 设备型号 [request setValue:[[UIDevice currentDevice] model] forHTTPHeaderField:@"deviceModel"]; /// 系统版本 [request setValue:[UIDevice currentDevice].systemVersion forHTTPHeaderField:@"osVersion"]; /// 系统类型 [request setValue:@"IOS" forHTTPHeaderField:@"osType"]; /// 必传 [request setValue:@"APP" forHTTPHeaderField:@"loginChannel"]; /// 版本 NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; [request setValue:version forHTTPHeaderField:@"appVersion"]; /// 发布渠道 #ifdef DEBUG [request setValue:@"develop" forHTTPHeaderField:@"version"]; #else [request setValue:@"produce" forHTTPHeaderField:@"version"]; #endif NSString *deviceTokens = [UserDefaults objectForKey:DeviceTokenKey]; /// APNS Token [request setValue:STRINGHASVALUE(deviceTokens) ? deviceTokens : @"" forHTTPHeaderField:@"deviceToken"]; NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0]; NSArray *array = [language componentsSeparatedByString:@"-"]; NSString *currentLanguage = array[0]; NSString *current = [currentLanguage isEqualToString:@"en"] ? F(@"%@_US", currentLanguage) : F(@"%@_CN", currentLanguage); [request setValue:current forHTTPHeaderField:@"Accept-Language"]; return request; } - (NSMutableArray *)deviceList { if (!_deviceList)_deviceList = [NSMutableArray new]; return _deviceList; } @end