昨天说了一下YTKNetwork的基础功能的使用,今天说一下对于高级功能的使用,具体如下:
1)YTKUrlFilterProtocol接口
YTKUrlFilterProtocol接口用于实现对网络请求URL或参数的重写,可以统一为网络请求加上一些参数,或者修改一些路径。
例如:当需要为每个网络请求加上客户端的版本号作为参数。如下一个YTKUrlArgumentsFilter类,实现YTKUrlFilterProtocol接口:
// YTKUrlArgumentsFilter.h
//实现自己的URL拼接工具类
@interfaceYTKUrlArgumentsFilter:NSObject
+ (YTKUrlArgumentsFilter *)filterWithArguments:(NSDictionary*)arguments;
- (NSString*)filterUrl:(NSString*)originUrlwithRequest:(YTKBaseRequest *)request;
@end
// YTKUrlArgumentsFilter.m
@implementationYTKUrlArgumentsFilter{
NSDictionary*_arguments;
}
+ (YTKUrlArgumentsFilter *)filterWithArguments:(NSDictionary*)arguments {
return[[selfalloc]initWithArguments:arguments];
}
- (id)initWithArguments:(NSDictionary*)arguments {
self = [superinit];
if(self) {
_arguments = arguments;
}
returnself;
}
- (NSString*)filterUrl:(NSString*)originUrlwithRequest:(YTKBaseRequest *)request {
return[YTKUrlArgumentsFilterurlStringWithOriginUrlString:originUrlappendParameters:_arguments];
}
@end
通过以上YTKUrlArgumentsFilter类,就可以用以下代码方便地为网络请求增加统一的参数,如增加当前客户端的版本号:
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
[selfsetupRequestFilters];
returnYES;
}
- (void)setupRequestFilters {
NSString*appVersion = [[[NSBundlemainBundle]infoDictionary]objectForKey:@"CFBundleShortVersionString"];
YTKNetworkConfig *config = [YTKNetworkConfigsharedConfig];
YTKUrlArgumentsFilter *urlFilter = [YTKUrlArgumentsFilterfilterWithArguments:@{@"version": appVersion}];
[configaddUrlFilter:urlFilter];
}
2)YTKBatchRequest类
YTKBatchRequest类:用于方便地发送批量的网络请求,YTKBatchRequest是一个容器类,它可以放置多个YTKRequest子类,并统一处理这多个网络请求的成功和失败。
#import"YTKBatchRequest.h"
#import"GetImageApi.h"
#import"GetUserInfoApi.h"
- (void)sendBatchRequest {
GetImageApi *a = [[GetImageApialloc]initWithImageId:@"1.jpg"];
GetImageApi *b = [[GetImageApialloc]initWithImageId:@"2.jpg"];
GetImageApi *c = [[GetImageApialloc]initWithImageId:@"3.jpg"];
GetUserInfoApi *d = [[GetUserInfoApialloc]initWithUserId:@"123"];
YTKBatchRequest *batchRequest = [[YTKBatchRequestalloc]initWithRequestArray:@[a, b, c, d]];
[batchRequeststartWithCompletionBlockWithSuccess:^(YTKBatchRequest *batchRequest) {
NSLog(@"succeed");
NSArray*requests = batchRequest.requestArray;
GetImageApi *a = (GetImageApi *)requests[0];
GetImageApi *b = (GetImageApi *)requests[1];
GetImageApi *c = (GetImageApi *)requests[2];
GetUserInfoApi *user = (GetUserInfoApi *)requests[3];
// deal with requests result ...
}failure:^(YTKBatchRequest *batchRequest) {
NSLog(@"failed");
}];
}
3)YTKChainRequest类
用于管理有相互依赖的网络请求。
例如,用户在注册时,先发送注册的Api,如果注册成功,再发送读取用户信息的Api。并且读取用户信息的Api需要使用注册成功返回的用户id号。如果注册失败,则不发送读取用户信息的Api。
以下是具体的代码示例,在示例中,我们在sendChainRequest方法中设置好了Api相互的依赖,然后就可以通过chainRequestFinished回调来处理所有网络请求都发送成功的逻辑。如果有任何其中一个网络请求失败,则会触发chainRequestFailed回调。
- (void)sendChainRequest {
RegisterApi *reg = [[RegisterApialloc]initWithUsername:@"username"password:@"password"];
YTKChainRequest *chainReq = [[YTKChainRequestalloc]init];
[chainReqaddRequest:regcallback:^(YTKChainRequest *chainRequest, YTKBaseRequest *baseRequest) {
RegisterApi *result = (RegisterApi *)baseRequest;
NSString*userId = [resultuserId];
GetUserInfoApi *api = [[GetUserInfoApialloc]initWithUserId:userId];
[chainRequestaddRequest:apicallback:nil];
}];
chainReq.delegate = self;
// start to send request
[chainReqstart];
}
- (void)chainRequestFinished:(YTKChainRequest *)chainRequest {
// all requests are done
}
- (void)chainRequestFailed:(YTKChainRequest *)chainRequest failedBaseRequest:(YTKBaseRequest*)request {
// some one of request is failed
}
4)显示上次缓存的内容
在实际开发中,有一些内容可能会加载很慢,我们想先显示上次的内容,等加载成功后,再用最新的内容替换上次的内容。有时候由于网络处于断开状态,我们想显示上次缓存中的内容。这时可以使用YTKReqeust的直接加载缓存的高级用法。
具体的方法是直接使用YTKRequest的- (BOOL)loadCacheWithError:方法即可获得上次缓存的内容。当然,你需要把- (NSInteger)cacheTimeInSeconds覆盖,返回一个大于等于0的值,这样才能开启YTKRequest的缓存功能,否则默认情况下,缓存功能是关闭的。
以下是一个示例,我们在加载用户信息前,先取得上次加载的内容,然后再发送请求,请求成功后再更新界面:
- (void)loadCacheData {
NSString*userId =@"1";
GetUserInfoApi *api = [[GetUserInfoApialloc]initWithUserId:userId];
if([apiloadCacheWithError:nil]) {
NSDictionary*json = [apiresponseJSONObject];
NSLog(@"json =%@", json);
// show cached data
}
[apistartWithCompletionBlockWithSuccess:^(YTKBaseRequest *request) {
NSLog(@"update ui");
}failure:^(YTKBaseRequest *request) {
NSLog(@"failed");
}];
}
5)上传文件
我们可以通过覆盖constructingBodyBlock方法,来方便地上传图片等附件,如下是一个示例:
// YTKRequest.h
#import"YTKRequest.h"
@interfaceUploadImageApi:YTKRequest
- (id)initWithImage:(UIImage *)image;
- (NSString*)responseImageId;
@end
// YTKRequest.m
@implementationUploadImageApi{
UIImage *_image;
}
- (id)initWithImage:(UIImage *)image {
self = [superinit];
if(self) {
_image = image;
}
returnself;
}
- (YTKRequestMethod)requestMethod{
returnYTKRequestMethodPOST;
}
- (NSString*)requestUrl{
return@"/iphone/image/upload";
}
- (AFConstructingBlock)constructingBodyBlock{
return^(id formData) {
NSData*data =UIImageJPEGRepresentation(_image,0.9);
NSString*name =@"image";
NSString*formKey =@"image";
NSString*type =@"image/jpeg";
[formDataappendPartWithFileData:dataname:formKeyfileName:namemimeType:type];
};
}
- (id)jsonValidator{
return@{@"imageId": [NSStringclass] };
}
- (NSString*)responseImageId{
NSDictionary*dict = self.responseJSONObject;
returndict[@"imageId"];
}
@end
通过如上代码,我们创建了一个上传图片,然后获得服务器返回的imageId的网络请求Api。
6)定制网络请求的HeaderField
通过覆盖requestHeaderFieldValueDictionary方法返回一个dictionary对象来自定义请求的HeaderField,返回的dictionary,其key即为HeaderField的key,value为HeaderField的Value,需要注意的是key和value都必须为string对象。
7)定制buildCustomUrlRequest
通过覆盖buildCustomUrlRequest方法,返回一个NSUrlRequest对象来达到完全自定义请求的需求。该方法定义在YTKBaseRequest类,如下:
//构建自定义的UrlRequest,
//若这个方法返回非nil对象,会忽略requestUrl, requestArgument, requestMethod, requestSerializerType,requestHeaderFieldValueDictionary
- (NSURLRequest*)buildCustomUrlRequest;
如注释所言,如果构建自定义的request,会忽略其他的一切自定义request的方法,例如requestUrl,requestArgument,requestMethod,requestSerializerType,requestHeaderFieldValueDictionary等等。一个上传gzippingData的示例如下:
- (NSURLRequest*)buildCustomUrlRequest {
NSData*rawData = [[_eventsjsonString]dataUsingEncoding:NSUTF8StringEncoding];
NSData*gzippingData = [NSDatagtm_dataByGzippingData:rawData];
NSMutableURLRequest*request = [NSMutableURLRequestrequestWithURL:[NSURLURLWithString:self.requestUrl]];
[requestsetHTTPMethod:@"POST"];
[requestaddValue:@"application/json;charset=UTF-8"forHTTPHeaderField:@"Content-Type"];
[requestaddValue:@"gzip"forHTTPHeaderField:@"Content-Encoding"];
[requestsetHTTPBody:gzippingData];
returnrequest;
}
网友评论
return[YTKUrlArgumentsFilterurlStringWithOriginUrlString:originUrlappendParameters:_arguments];
}
这里 return 的这个方法,是在哪里的 ??