网络相关iOS Developer

iOS开发--YTKNetwork高级功能

2016-12-28  本文已影响988人  一个有个性的女汉子

昨天说了一下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;

}

上一篇下一篇

猜你喜欢

热点阅读