开篇语:
写到这,你发现没有,在使用YTKNetwork写接口的时候,每一个接口都必须继承YTKRequest类,也就是说如果你有十个接口,就需要写十个请求类。这对于小团队来说,是不是麻烦了点呢?
解决办法:
提取一个通用的request类来统一处理所有请求。
想法很简单,就是自定义一个类,然后把你所需要的参数:请求类型、URL、参数等传进去。可是,仔细分析之后,我们发现YTKBaseRequest类中,关键的参数都写成了方法。如下:
- (NSString *)baseUrl;
- (NSString *)requestUrl;
- (NSString *)cdnUrl;
看来YTKNetwork从最初设计的时候,就不想让人动态设置,反而是想让每一个请求类都重写这些方法。我们有什么办法吗?当然有:在子类中声明相同名字的属性。YTKBaseRequest中的想法方法,即可理解为这些属性的Get方法。
大概就是这样子:
@interface HXRequest : YTKRequest
/**
请求URL地址
*/
@property(nonatomic, strong) NSString * requestUrl;
@end
那么我们有必要把所有方法都声明出来吗?当然不必要,例如 baseUrl ,一般来说是固定不变的。在HXRequest 类中,我们可以根据自己的偏好,修改description信息,定义统一的请求头,错误处理方法,统一处理401等。
下面是整个类的简单写法:
HXRequest.h
#import "YTKRequest.h"
@class HXRequest;
typedef void(^HXRequestCompletionBlock)(__kindof HXRequest *request,NSDictionary *result, BOOL success);
typedef void(^HXRequestCompletionFailureBlock)(__kindof HXRequest *request,NSString *errorInfo);
@interface HXRequest : YTKRequest
/**
请求URL地址
*/
@property(nonatomic, strong) NSString * requestUrl;
/**
请求参数
*/
@property(nonatomic, strong) id requestArgument;
/**
错误提示
*/
@property(nonatomic, strong) NSString * errorInfo;
/**
请求类型
*/
@property(nonatomic, assign) YTKRequestSerializerType requestSerializerType;
/**
是否校验json数据格式,默认yes
*/
@property(nonatomic, assign) BOOL verifyJSONFormat;
/**
开始请求数据
@param success 成功回调
@param failure 失败回调,返回error信息
*/
- (void)startWithCompletionBlockWithSuccess:(nullable HXRequestCompletionBlock)success
failure:(nullable HXRequestCompletionFailureBlock)failure;
@end
HXRequest.m
#import "HXRequest.h"
#import "YTKNetworkConfig.h"
#import "HXLoginManager.h"
@implementation HXRequest
- (instancetype)init
{
self = [super init];
if (self) {
[YTKNetworkConfig sharedConfig].debugLogEnabled = YES; //开启Debug模式
self.verifyJSONFormat = YES;
}
return self;
}
- (NSString *)baseUrl {
return @"https://www.baidu.com";
}
- (NSTimeInterval)requestTimeoutInterval {
return 10;
}
- (id)jsonValidator {
if (self.verifyJSONFormat) {
return @{
@"data": [NSObject class],
@"success": [NSNumber class],
@"message": [NSString class]
};
}else
{
return nil;
}
}
- (void)startWithCompletionBlockWithSuccess:(nullable HXRequestCompletionBlock)success
failure:(nullable HXRequestCompletionFailureBlock)failure
{
[super startWithCompletionBlockWithSuccess:^(__kindof YTKBaseRequest * _Nonnull request) {
NSDictionary *result = [request responseJSONObject];
BOOL isSuccess = YES;
//校验格式
if (self.verifyJSONFormat) {
isSuccess = [[result objectForKey:@"success"] boolValue];
}
success(request,result,isSuccess);
} failure:^(__kindof YTKBaseRequest * _Nonnull request) {
NSLog(@"%@",self.description);
failure(request,self.errorInfo);
}];
}
- (NSString *)description {
//打印自己认为重要的信息
return [NSString stringWithFormat:@"%@ \nstatusCode:%ld\nresponseJSONObject:\n%@",super.description,self.responseStatusCode,self.responseJSONObject];
}
- (NSString *)errorInfo {
NSString * info = @"";
if (request && request.error) {
if (request.error.code==NSURLErrorNotConnectedToInternet) {
info = @"请检查网络!";
}else if (request.error.code==NSURLErrorTimedOut) {
info = @"请求超时,请重试!";
}else if (request.responseStatusCode == 401) {
info = @"401";
}else if (request.responseStatusCode == 403) {
info = @"403";
}else if (request.responseStatusCode == 404) {
info = @"404";
}else if (request.responseStatusCode == 500) {
info = @"服务器报错,请稍后再试!";
}else
{
info = @"获取数据失败,请重试!";
}
}
return info;
}
@end
这里你会发现,我没有实现requestMethod方法,是的,一般来说,一个接口定义好之后,就不会再修改requestMethod了,所以,我打算再定义一个HXGetRequest,Get请求专用方法。
#import "HXRequest.h"
@interface HXGetRequest : HXRequest
/**
GET 请求
@param url 网址
@param argument 参数
@return HXRequest
*/
- (id)initWithRequestUrl:(NSString *)url argument:(NSDictionary *)argument;
@end
#import "HXGetRequest.h"
@implementation HXGetRequest
- (id)initWithRequestUrl:(NSString *)url argument:(NSDictionary *)argument {
self = [super init];
if (self) {
self.requestUrl = url;
self.requestArgument = argument;
}
return self;
}
- (YTKRequestMethod)requestMethod {
return YTKRequestMethodGET;
}
@end
同理,我们也可以定义POST、PUT、DELETE 等相关的类。这里就不再举例说明了。
下面让我们来看看HXGetRequest如何使用吧!
HXGetRequest * request = [[HXGetRequest alloc] initWithRequestUrl:@"api/requestUrl" argument:nil];
[request startWithCompletionBlockWithSuccess:^(__kindof HXRequest *request, NSDictionary *result, BOOL success) {
if (success) {
//成功
}else
{
//失败
}
} failure:^(__kindof HXRequest *request, NSString *errorInfo) {
//错误
NSLog(@"%@",errorInfo);
}];
怎么样,想使用的时候随手拿来用,是不是方便了很多呢~