YTKNetwork 基本用法

YTKNetwork Basic Guide:YTKNetwork 基本指导

In the article, we will introduce the basic usage of YTKNetwork. 在这片文章中,我们将介绍YTKNetwork的基本使用方法。

YTKNetwork's basic composition YTKNetwork的基本组成

YTKNetwork mainly contains the following classes: YTKNetwork主要包含以下课程:
*NETWorkConfig:it's used for setting global network host address and CDN address. YTKNetworkConfig:用于设定全球网络主机地址和CDN地址。
*YTKRequest :it's the parent of all the detailed network request classes. All network request classes should inherit it. Every subclass of YTKRequest represents a specific network request. YTKRequest:父类的所有详细的网络请求。所有的网络请求应该继承它的类。每一子类YTKRequest代表一个特定的网络请求。

We will explain the above 2 classes' detailed usage below. 我们将解释以下2类以上的详细用法。

YTKNetworkConfig class YTKNetworkConfig类

YTKNetworkConfig class has 2 usages: YTKNetworkConfig类有两个用途:
1.Set global network host address and CDN address. 建立全球网络主机地址和CDN地址。
2.Manage the filters which implemented YTKUrlFilterProtocol protocol(we will discuss it in pro usage guide)。 管理的过滤器实现YTKUrlFilterProtocol协议(我们将讨论它在专业使用指南)。
We use YTKNetworkConfig to set global network host address because:

我们使用YTKNetworkConfig设置全球网络主机地址,因为:
1.According to the Do Not Repeat Yourself principle,we should write the host address only once. 根据不重复自己的原则,我们应该只写一次主机地址。
2.In practise, our testers need to switch host addresses at runtime. YTKNetworkConfig can satisfy such requirement. 在实践中,我们的测试人员需要在运行时切换主机地址。YTKNetworkConfig可以满足这样的要求。
We should set YTKNetworkConfig's property at the beggining of app launching, the sample is below:

我们应该设置YTKNetworkConfig的属性在应用程序启动的发出召唤,下面的示例:

- (BOOL)application:(UIApplication *)application 
   didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
   YTKNetworkConfig *config = [YTKNetworkConfig sharedInstance];
   config.baseUrl = @"http://yuantiku.com";
   config.cdnUrl = @"http://fen.bi";
}

After setting, all network requests will use YTKNetworkConfig's baseUrl property as their host addresses, and they will use the cdnUrl property of YTKNetworkConfig as their CDN addresses.

设置后,所有的网络请求将使用YTKNetworkConfig baseUrl作为他们的主机地址,他们将使用cdnUrl作为YTKNetworkConfig 的CDN地址。
If we want to switch server address, we can just change YTKNetworkConfig's baseUrl property.

如果我们想要切换服务器地址,我们可以改变YTKNetworkConfig baseUrl属性。

YTKRequest class YTKRequest 类

The design idea of YTKNetwork is that every specific network request should be a object. So after using YTKNetwork, all your request classes should inherit YTKNetwork. Through overwriting the methods of super class, you can build your own specific and distinguished request. The key idea behind this is somewhat like the Command pattern.

YTKNetwork的设计理念是,每一个特定的网络请求应该是一个对象。所以使用YTKNetwork后,所有你的要求应该继承YTKNetwork类。通过重写父类的方法,您可以构建自己的特定的和杰出的请求。这背后的关键理念有点像命令模式。
For example, if we want to send a POST request to http://www.yuantiku.com/iphone/register,with username and password as arguments, then the class should be as following:

例如,如果我们想要发送一个POST请求到http://www.yuantiku.com/iphone/register,用户名和密码作为参数,那么类应该如下:

// RegisterApi.h
#import "YTKRequest.h"

@interface RegisterApi : YTKRequest

- (id)initWithUsername:(NSString *)username password:(NSString *)password;

@end


// RegisterApi.m


#import "RegisterApi.h"

@implementation RegisterApi {
    NSString *_username;
    NSString *_password;
}

- (id)initWithUsername:(NSString *)username password:(NSString *)password {
    self = [super init];
    if (self) {
        _username = username;
        _password = password;
    }
    return self;
}

- (NSString *)requestUrl {
    // “http://www.yuantiku.com” is set in YTKNetworkConfig, so we ignore it
    return @"/iphone/register";
}

- (YTKRequestMethod)requestMethod {
    return YTKRequestMethodPost;
}

- (id)requestArgument {
    return @{
        @"username": _username,
        @"password": _password
    };
}

@end

888888888888888888888888

In above example: 在上面的例子:

Through overwriting requestUrl method, we've indicated the detailed url. Bacause host address has been set in YTKNetworkConfig, we should not write the host address in requestUrl method.
通过覆盖requestUrl方法,我们表示详细的url。因为在YTKNetworkConfig主机地址,我们不应该写requestUrl主机地址的方法。
Through overwriting requestMethod method, we've indicated the use of the POST method.
通过覆盖requestMethod方法,我们使用POST方法。
Through overwriting requestArgument method, we've provided the POST data. If arguments username and password contain any charaters which should be escaped, the library will do it automatically.
通过覆盖requestArgument方法,我们提供了POST数据。如果用户名和密码参数包含任何特征应该逃,图书馆会自动。
Call RegisterApi 叫RegisterApi
OK, how can we use the RegisterApi? We can call it in the login view controller. After initializing the instance, we can call its start or startWithCompletionBlockWithSuccess method to send the request to the network request queue.

好的,我们如何使用RegisterApi吗?我们可以叫它登录视图控制器。初始化实例后,可以调用它的启动或startWithCompletionBlockWithSuccess方法发送请求到网络请求队列。

Then we can get network response by block or delegate mechanism.

然后我们可以通过阻止或委托网络响应机制。

- (void)loginButtonPressed:(id)sender {
    NSString *username = self.UserNameTextField.text;
    NSString *password = self.PasswordTextField.text;
    if (username.length > 0 && password.length > 0) {
        RegisterApi *api = [[RegisterApi alloc] initWithUsername:username password:password];
        [api startWithCompletionBlockWithSuccess:^(YTKBaseRequest *request) {
            // you can use self here, retain cycle won't happen
            NSLog(@"succeed");

        } failure:^(YTKBaseRequest *request) {
            // you can use self here, retain cycle won't happen
            NSLog(@"failed");
        }];
    }
}

Kindly be noted that you can use self directly in the block where the retain cycle won't happen. Because YTKRequest will set callback block to nil, so the block will be released right after the network request completed.

请注意,您可以使用直接自我的块保留周期不会发生。因为YTKRequest将回调块为零,所以块将网络请求完成后发布。

Besides the block callback, YTKRequest also support delegate callback method. The example is below:

除了块回调,YTKRequest也支持委托回调方法。下面的例子是:

- (void)loginButtonPressed:(id)sender {
    NSString *username = self.UserNameTextField.text;
    NSString *password = self.PasswordTextField.text;
    if (username.length > 0 && password.length > 0) {
        RegisterApi *api = [[RegisterApi alloc] initWithUsername:username password:password];
        api.delegate = self;
        [api start];
    }
}

- (void)requestFinished:(YTKBaseRequest *)request {
    NSLog(@"succeed");
}

- (void)requestFailed:(YTKBaseRequest *)request {
    NSLog(@"failed");
}

Verify response JSON 验证响应JSON
The response JSON from the server cannnot be always trusted. Client may crash if the data is returned in faulty format from the server.

来自服务器的响应JSON总不会是可信的。客户可能会崩溃,如果数据从服务器返回错误的格式。

YTKRequest provides a simple way to verity the respose JSON.

YTKRequest真实性respose JSON提供了一个简单的方法。

For example, let's say we need to send a GET request to http://www.yuantiku.com/iphone/users address with a argument named userId. The server will return the target user's information, including nickname and level. We shall guarantee that the response type of nickname is string and the type of level is number. To ensure this, we can overwrite the jsonValidator as following:

举个例子,假设我们需要发送一个GET请求到http://www.yuantiku.com/iphone/users地址和一个名叫userId参数。服务器将返回目标用户的信息,包括昵称和水平。我们将保证昵称的响应类型是字符串和水平数的类型。为了确保这一点,我们可以覆盖jsonValidator如下:

- (id)jsonValidator {
    return @{
        @"nick": [NSString class],
        @"level": [NSNumber class]
    };
}
The whole code sample is below:  整个代码示例如下:

// GetUserInfoApi.h
#import "YTKRequest.h"

@interface GetUserInfoApi : YTKRequest

- (id)initWithUserId:(NSString *)userId;

@end


// GetUserInfoApi.m
#import "GetUserInfoApi.h"

@implementation GetUserInfoApi {
    NSString *_userId;
}

- (id)initWithUserId:(NSString *)userId {
    self = [super init];
    if (self) {
        _userId = userId;
    }
    return self;
}

- (NSString *)requestUrl {
    return @"/iphone/users";
}

- (id)requestArgument {
    return @{ @"id": _userId };
}

- (id)jsonValidator {
    return @{
        @"nick": [NSString class],
        @"level": [NSNumber class]
    };
}

@end

Here is some other samples:这里有一些其他的样品:

Require return String array: 需要返回字符串数组:

- (id)jsonValidator {
    return @[ [NSString class] ];
}
Here is one complex sample from our company:  这是一个复杂的样品从我们的公司:
- (id)jsonValidator {
    return @[@{
        @"id": [NSNumber class],
        @"imageId": [NSString class],
        @"time": [NSNumber class],
        @"status": [NSNumber class],
        @"question": @{
            @"id": [NSNumber class],
            @"content": [NSString class],
            @"contentType": [NSNumber class]
        }
    }];
} 

Use CDN address 使用CDN地址
If you need to use CDN address in some of your requests, just overwrite the - (BOOL)useCDN; method, and return YESin the method.

如果你需要使用CDN地址在你的请求,只是覆盖——(BOOL)useCDN;方法,并返回YESin方法。

For example, if we have a interface for image downloading, and the address is http://fen.bi/image/imageId with the host http://fen.bi as the CDN address. Then the code should be below:

例如,如果我们有一个界面图片下载,地址是http://fen。bi /图像/ imageId与宿主http://fen。bi作为CDN地址。然后下面的代码应该是:

// GetImageApi.h
#import "YTKRequest.h"

@interface GetImageApi : YTKRequest
- (id)initWithImageId:(NSString *)imageId;
@end

// GetImageApi.m
#import "GetImageApi.h"

@implementation GetImageApi {
    NSString *_imageId;
}

- (id)initWithImageId:(NSString *)imageId {
    self = [super init];
    if (self) {
        _imageId = imageId;
    }
    return self;
}

- (NSString *)requestUrl {
    return [NSString stringWithFormat:@"/iphone/images/%@", _imageId];
}

- (BOOL)useCDN {
    return YES;
}

@end

Resumable Downloading 可恢复的下载
If you want to enable resumable downloading, you just need to overwrite the resumableDownloadPath method and provide a temporary path to save the half-downloaded data.

如果你想使可恢复的下载,你只需要覆盖resumableDownloadPath方法和提供一个临时路径保存half-downloaded数据。

We can modify above example to support resumable downloading.

我们可以修改上面的例子来支持可恢复的下载。

@implementation GetImageApi {
    NSString *_imageId;
}

- (id)initWithImageId:(NSString *)imageId {
    self = [super init];
    if (self) {
        _imageId = imageId;
    }
    return self;
}

- (NSString *)requestUrl {
    return [NSString stringWithFormat:@"/iphone/images/%@", _imageId];
}

- (BOOL)useCDN {
    return YES;
}

- (NSString *)resumableDownloadPath {
    NSString *libPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *cachePath = [libPath stringByAppendingPathComponent:@"Caches"];
    NSString *filePath = [cachePath stringByAppendingPathComponent:_imageId];
    return filePath;
}

@end

Cache response data 缓存响应数据
We've implemented the GetUserInfoApi before, which is used for getting user information.

我们已经实现了GetUserInfoApi之前,用于获取用户信息。

We may want to cache the response. In the following example, we overwrite the cacheTimeInSeconds method, then our API will automatically cache data for specified amount of time. If the cached data is not expired, the api's start and startWithCompletionBlockWithSuccess will return cached data as a result directly.

我们可能想要缓存响应。在接下来的例子中,我们覆盖cacheTimeInSeconds方法,那么我们的API为指定的时间会自动缓存数据。如果缓存数据没有过期,api的开始和startWithCompletionBlockWithSuccess将直接返回缓存的数据结果。

@implementation GetUserInfoApi {
    NSString *_userId;
}

- (id)initWithUserId:(NSString *)userId {
    self = [super init];
    if (self) {
        _userId = userId;
    }
    return self;
}

- (NSString *)requestUrl {
    return @"/iphone/users";
}

- (id)requestArgument {
    return @{ @"id": _userId };
}

- (id)jsonValidator {
    return @{
        @"nick": [NSString class],
        @"level": [NSNumber class]
    };
}

- (NSInteger)cacheTimeInSeconds {
    // cache 3 minutes, which is 60 * 3 = 180 seconds
    return 60 * 3;
}

@end

The cache mechanism is transparent to the controller, which means the request caller may get the result right after invoking the request without casuing any real network traffic as long as its cached data remains valid.

缓存机制对控制器是透明的,这意味着请求调用者可能会调用请求的结果后没有因为任何真正的网络流量,只要其缓存的数据仍然有效。

The above code samples are available in the YTKNetworkDemo project.

上面的代码样本YTKNetworkDemo项目中是可用的。


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,165评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,503评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,295评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,589评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,439评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,342评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,749评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,397评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,700评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,740评论 2 313
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,523评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,364评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,755评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,024评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,297评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,721评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,918评论 2 336

推荐阅读更多精彩内容

  • 记得呀 那是小学几年级的时候 和小霸王做同桌 那一年做的是一体的长板凳 我起立回答问题 他把凳子无声无息的撤到后面...
    橘子与长颈鹿阅读 103评论 0 1
  • 在一次事故中 我丧失了身体的某些记忆 虽然我仍完好的呈现在这里 但是意识已经近乎死过一次 某些通道关闭了 曾经自然...
    满_3539阅读 188评论 3 1
  • 有时候我觉得:生活不止有眼前的苟且,还有你眼不能见的苟且! 但是人活着,总不能因为外力而停止前进吧。你是愿意做一个...
    妍玖久阅读 214评论 0 1
  • 〖每日拔拔草〗三度思维空性 1.和陈蓓蓓去华芝整形其实一个私心的念头就是希望她能接受这种分享经济模式,这样我就有了...
    lindacheng2017阅读 126评论 0 0