美文网首页网络相关iOS Developer
iOS开发--YTKNetwork高级功能

iOS开发--YTKNetwork高级功能

作者: 一个有个性的女汉子 | 来源:发表于2016-12-28 19:26 被阅读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;

    }

    相关文章

      网友评论

      • embraceChange:你好,问一下 - (NSString*)filterUrl:(NSString*)originUrlwithRequest:(YTKBaseRequest *)request {

        return[YTKUrlArgumentsFilterurlStringWithOriginUrlString:originUrlappendParameters:_arguments];

        }

        这里 return 的这个方法,是在哪里的 ??

      本文标题:iOS开发--YTKNetwork高级功能

      本文链接:https://www.haomeiwen.com/subject/nktuvttx.html