结合PromiseKit和YTKNetwork的网络请求组件,地址:PromiseYTKNetwork
一、 安装
pod 'PromiseYTKNetwork'
二、 配置
1. 配置baseurl
这里监听了App启动设置基本配置 切换环境时重新配置即可
+ (void)load {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(initThirdSDKsWhenApplicationDidFinishLaunching:) name:UIApplicationDidFinishLaunchingNotification object:nil];
}
+ (void)initThirdSDKsWhenApplicationDidFinishLaunching:(NSNotification *)info {
NSLog(@"%@", info.userInfo);
YTKNetworkConfig *networkConfig = [YTKNetworkConfig sharedConfig];
// 配置域名
networkConfig.baseUrl = API_HOST;
// 资源域名
networkConfig.cdnUrl = API_json_HOST;
}
2. 配置基本请求
1. 新建类继承PromiseRequest
#import "PromiseRequest.h"
NS_ASSUME_NONNULL_BEGIN
@interface BTPromiseRequest : PromiseRequest
@end
NS_ASSUME_NONNULL_END
2. 实现相关方法
#import "BTPromiseRequest.h"
@implementation BTPromiseRequest
/// 设置请求头,验签
- (NSDictionary<NSString *,NSString *> *)requestHeaderFieldValueDictionary {
NSMutableDictionary *requestSerializers = [NSMutableDictionary dictionary];
requestSerializers[@"Content-Type"] = @"application/json";
requestSerializers[@"User-Agent"] = userAgent;
requestSerializers[@"platform"] = @"iOSApp";
requestSerializers[@"version"] = [NSString stringWithFormat:@"V-%@", kAppVersion];
if (token) {
requestSerializers[@"X-bt-Json-Api-Token"] = token;
NSString *timeNum = timeNum;
requestSerializers[@"X-bt-Json-Api-Signature-Timestamp"] = timeNum;
NSString *randomNum = [NSString stringWithFormat:@"%d",arc4random() % 10000];
requestSerializers[@"X-bt-Json-Api-Nonce"] = randomNum;
NSString *Signature = [PUB_INTERFACE sha1:[NSString stringWithFormat:@"%@%@%@", token, randomNum, timeNum]];
requestSerializers[@"X-bt-Json-Api-Signature"] = Signature;
}
return requestSerializers;
}
/// 超时时间
- (NSTimeInterval)requestTimeoutInterval {
return 15;
}
@end
其他主要可设置的配置
-
取消请求
- (void)stop; -
特殊请求设置域名
- (NSString *)baseUrl;
- 设置请求路径
- (NSString *)requestUrl;
- 设置资源域名
- (NSString *)cdnUrl;
- 设置请求参数
- (nullable id)requestArgument;
- 设置请求方式
- (YTKRequestMethod)requestMethod;
- 请求和接收解析类型
- (YTKRequestSerializerType)requestSerializerType;
```
- (YTKResponseSerializerType)responseSerializerType;
```
3. 发送请求
/// 发起请求
- (AnyPromise *)launch;
4. 使用
1. 基本使用
-
OC
接口:
banner/index新建
HomeBannerRequest继承自BTPromiseRequest#import "HomeBannerRequest.h" @implementation HomeBannerRequest - (NSString *)requestUrl { return @"/banner/index"; } - (YTKRequestMethod)requestMethod { return YTKRequestMethodPOST; } @end发送请求监听结果
HomeBannerRequest *bannerReq = [[HomeBannerRequest alloc] init]; [bannerReq launch].then(^(NSDictionary *response) { NSLog(@"🚩🚩🚩🚩🚩🚩🚩🚩🚩🚩%@", response); }).catch(^(NSError *error){ NSLog(@"🚩🚩🚩🚩🚩🚩🚩🚩🚩🚩%@", error); }).ensure(^{ // 隐藏HUD NSLog(@"无论成功还是失败,都结束了"); }); // 取消请求 // [bannerReq stop];打印结果:
-
Swift
接口:
/Invoice/Order/List/// 可开票订单 class InvoiceOrderListRequest: BTPromiseRequest { /// 请求方式 override func requestMethod() -> YTKRequestMethod { return .POST } /// 接口路径 override func requestUrl() -> String { return "/Invoice/Order/List" } /// 统一域名,通过YTKNetworkConfig配置,yapi地址这里也可以重写 override func baseUrl() -> String { return "http://yapi.bt.com" } }发送
/// 请求数据
func loadNewData() {
let request = InvoiceOrderListRequest()
request.launch().done { response in
}.catch { error in
let errMsg = error.localizedDescription
}.finally {
self.tableView.mj_header.endRefreshing()
}
}
结果
2. 带参数请求
-
OC
接口: /Customer/Goods/QueryCategoryGoods
请求类:
QueryCategoryGoodsRequest#import "BTPromiseRequest.h" NS_ASSUME_NONNULL_BEGIN @interface QueryCategoryGoodsRequest : BTPromiseRequest - (instancetype)initWithCategoryCode:(NSString *)categoryCode channel:(NSString *)channel; @end NS_ASSUME_NONNULL_END#import "QueryCategoryGoodsRequest.h" @implementation QueryCategoryGoodsRequest { /// 分类编码 NSString *_categoryCode; /// 渠道,1:鼓励师推荐 2:其他 NSString *_channel; } - (instancetype)initWithCategoryCode:(NSString *)categoryCode channel:(NSString *)channel { if (self = [super init]) { _categoryCode = categoryCode; _channel = channel; } return self; } - (id)requestArgument { return @{ @"categoryCode": _categoryCode, @"channel": _channel }; } - (NSString *)requestUrl { return @"/Customer/Goods/QueryCategoryGoods"; } - (YTKRequestMethod)requestMethod { return YTKRequestMethodPOST; } @end使用:
QueryCategoryGoodsRequest *queryCategoryGoodsRequest = [[QueryCategoryGoodsRequest alloc] initWithCategoryCode:@"010401" channel:@"2"]; [queryCategoryGoodsRequest launch].then(^(NSDictionary *response) { NSLog(@"🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲%@", response); }).catch(^(NSError *error){ NSLog(@"🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲%@", error); }).ensure(^{ // 隐藏HUD NSLog(@"无论成功还是失败,都结束了"); });结果:
-
Swift
接口:
/Invoice/Submitclass InvoiceCommitRequest: BTPromiseRequest { private var invoiceTitle: String? private var taxNo: String? private var buyerType: String? private var invoiceItems: [Dictionary<String, Any>]? private var email: String? init(invoiceTitle: String, taxNo: String, buyerType: String, invoiceItems: [Dictionary<String, Any>], email: String) { super.init() self.invoiceTitle = invoiceTitle self.taxNo = taxNo self.buyerType = buyerType self.invoiceItems = invoiceItems self.email = email } /// 设置 /// - Returns: 请求参数 override func requestArgument() -> Any { let params = [ "invoiceTitle": invoiceTitle!, "taxNo": taxNo!, "buyerType": buyerType!, "invoiceItems": invoiceItems!, "email": email! ] as [String : Any] return params } override func requestMethod() -> YTKRequestMethod { return .POST } override func requestUrl() -> String { return "/Invoice/Submit" } }使用:
@IBAction func commitData(_ sender: CustomBtn) {
let buyerType = invoiceType == .personal ? "03" : "01"
let request = InvoiceCommitRequest(invoiceTitle: invoiceTitle!, taxNo: taxNo!, buyerType: buyerType, invoiceItems: invoiceItems!, email: email!)
request.launch().done { response in
}.catch { error in
}
}
结果:
3. 链式(嵌套)请求
第一个请求: /Bigclass/Course/Detail
#import "BTPromiseRequest.h"
NS_ASSUME_NONNULL_BEGIN
@interface BigclassCourseDetailRequest : BTPromiseRequest
- (instancetype)initWithSubjectId:(NSString *)subjectId StudyId:(NSString *)myStudyId;
@end
NS_ASSUME_NONNULL_END
#import "BigclassCourseDetailRequest.h"
@implementation BigclassCourseDetailRequest {
NSString *_subjectId;
NSString *_myStudyId;
}
- (instancetype)initWithSubjectId:(NSString *)subjectId StudyId:(NSString *)myStudyId {
if (self = [super init]) {
_subjectId = subjectId;
_myStudyId = myStudyId;
}
return self;
}
- (id)requestArgument {
return @{
@"subjectId": _subjectId,
@"myStudyId": _myStudyId,
@"version": @""
};
}
- (NSString *)requestUrl {
return @"/Bigclass/Course/Detail";
}
- (YTKRequestMethod)requestMethod {
return YTKRequestMethodPOST;
}
@end
第二个请求: /Bigclass/Course/progressData
#import "BTPromiseRequest.h"
NS_ASSUME_NONNULL_BEGIN
@interface BigclassCourseprogressDataRequest : BTPromiseRequest
- (instancetype)initWithSubjectId:(NSString *)subjectId StudyId:(NSString *)myStudyId version:(NSString *)version;
@end
NS_ASSUME_NONNULL_END
#import "BigclassCourseprogressDataRequest.h"
@implementation BigclassCourseprogressDataRequest {
NSString *_subjectId;
NSString *_myStudyId;
NSString *_version;
}
- (instancetype)initWithSubjectId:(NSString *)subjectId StudyId:(NSString *)myStudyId version:(NSString *)version {
if (self = [super init]) {
_subjectId = subjectId;
_myStudyId = myStudyId;
_version = version;
}
return self;
}
- (id)requestArgument {
return @{
@"subjectId": _subjectId,
@"myStudyId": _myStudyId,
@"version": _version
};
}
- (NSString *)requestUrl {
return @"/Bigclass/Course/progressData";
}
- (YTKRequestMethod)requestMethod {
return YTKRequestMethodPOST;
}
@end
使用:
BigclassCourseDetailRequest *courseDetailRequest = [[BigclassCourseDetailRequest alloc] initWithSubjectId:self.SubjectId StudyId:self.myStudyId];
[courseDetailRequest launch].then(^(NSDictionary *response) { // 第一个请求结果
NSString *version = response[@"message"][@"version"];
BigclassCourseprogressDataRequest *courseprogressDataRequest = [[BigclassCourseprogressDataRequest alloc] initWithSubjectId:self.SubjectId StudyId:self.myStudyId version:version];
return [courseprogressDataRequest launch];
}).then(^(NSDictionary *response) { // 第二个请求结果
NSLog(@"%@", response);
}).catch(^(NSError *error) {
NSLog(@"%@", error);
});
结果:
4. 组合(同时发起)请求
前者接口2
接口3: /Class/Trial
#import "ClassTrialRequest.h"
@implementation ClassTrialRequest {
NSString *_subjectId;
NSString *_myStudyId;
}
- (instancetype)initWithSubjectId:(NSString *)subjectId StudyId:(NSString *)myStudyId {
if (self = [super init]) {
_subjectId = subjectId;
_myStudyId = myStudyId;
}
return self;
}
- (id)requestArgument {
return @{
@"subjectId": _subjectId,
@"myStudyId": _myStudyId,
};
}
- (NSString *)requestUrl {
return @"/Class/Trial";
}
- (YTKRequestMethod)requestMethod {
return YTKRequestMethodPOST;
}
使用:
BigclassCourseDetailRequest *courseDetailRequest = [[BigclassCourseDetailRequest alloc] initWithSubjectId:self.SubjectId StudyId:self.myStudyId];
[courseDetailRequest launch].then(^(NSDictionary *response) { // 第一个请求结果
NSLog(@"第一个请求:%@", response);
NSString *version = response[@"message"][@"version"];
// 第二个
BigclassCourseprogressDataRequest *courseprogressDataRequest = [[BigclassCourseprogressDataRequest alloc] initWithSubjectId:self.SubjectId StudyId:self.myStudyId version:version];
// 第三个
ClassTrialRequest *trialRequest = [[ClassTrialRequest alloc] initWithSubjectId:self.SubjectId StudyId:self.myStudyId];
return PMKWhen(@[[courseprogressDataRequest launch], [trialRequest launch]]);
// return [courseprogressDataRequest launch];
}).then(^(NSArray <NSDictionary *> *responseArray) { // 组合请求结果
NSLog(@"第二、三个请求:%@", responseArray);
}).catch(^(NSError *error) {
NSLog(@"%@", error);
});
结果: