YTKNetwork Basic Guide:YTKNetwork 基本指導(dǎo)
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:用于設(shè)定全球網(wǎng)絡(luò)主機(jī)地址和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:父類的所有詳細(xì)的網(wǎng)絡(luò)請求汁讼。所有的網(wǎng)絡(luò)請求應(yīng)該繼承它的類僵控。每一子類YTKRequest代表一個特定的網(wǎng)絡(luò)請求欲间。
We will explain the above 2 classes' detailed usage below. 我們將解釋以下2類以上的詳細(xì)用法荤傲。
YTKNetworkConfig class YTKNetworkConfig類
YTKNetworkConfig class has 2 usages: YTKNetworkConfig類有兩個用途:
1.Set global network host address and CDN address. 建立全球網(wǎng)絡(luò)主機(jī)地址和CDN地址耻涛。
2.Manage the filters which implemented YTKUrlFilterProtocol protocol(we will discuss it in pro usage guide)呐伞。 管理的過濾器實現(xiàn)YTKUrlFilterProtocol協(xié)議(我們將討論它在專業(yè)使用指南)敌卓。
We use YTKNetworkConfig to set global network host address because:
我們使用YTKNetworkConfig設(shè)置全球網(wǎng)絡(luò)主機(jī)地址,因為:
1.According to the Do Not Repeat Yourself principle,we should write the host address only once. 根據(jù)不重復(fù)自己的原則,我們應(yīng)該只寫一次主機(jī)地址荸哟。
2.In practise, our testers need to switch host addresses at runtime. YTKNetworkConfig can satisfy such requirement. 在實踐中,我們的測試人員需要在運行時切換主機(jī)地址假哎。YTKNetworkConfig可以滿足這樣的要求。
We should set YTKNetworkConfig's property at the beggining of app launching, the sample is below:
我們應(yīng)該設(shè)置YTKNetworkConfig的屬性在應(yīng)用程序啟動的發(fā)出召喚,下面的示例:
- (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.
設(shè)置后,所有的網(wǎng)絡(luò)請求將使用YTKNetworkConfig baseUrl作為他們的主機(jī)地址,他們將使用cdnUrl作為YTKNetworkConfig 的CDN地址鞍历。
If we want to switch server address, we can just change YTKNetworkConfig's baseUrl property.
如果我們想要切換服務(wù)器地址,我們可以改變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的設(shè)計理念是,每一個特定的網(wǎng)絡(luò)請求應(yīng)該是一個對象。所以使用YTKNetwork后,所有你的要求應(yīng)該繼承YTKNetwork類劣砍。通過重寫父類的方法,您可以構(gòu)建自己的特定的和杰出的請求惧蛹。這背后的關(guān)鍵理念有點像命令模式。
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:
例如,如果我們想要發(fā)送一個POST請求到http://www.yuantiku.com/iphone/register,用戶名和密碼作為參數(shù),那么類應(yīng)該如下:
// 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方法,我們表示詳細(xì)的url香嗓。因為在YTKNetworkConfig主機(jī)地址,我們不應(yīng)該寫requestUrl主機(jī)地址的方法。
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數(shù)據(jù)靠娱。如果用戶名和密碼參數(shù)包含任何特征應(yīng)該逃,圖書館會自動。
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.
好的,我們?nèi)绾问褂肦egisterApi嗎?我們可以叫它登錄視圖控制器掠兄。初始化實例后,可以調(diào)用它的啟動或startWithCompletionBlockWithSuccess方法發(fā)送請求到網(wǎng)絡(luò)請求隊列像云。
Then we can get network response by block or delegate mechanism.
然后我們可以通過阻止或委托網(wǎng)絡(luò)響應(yīng)機(jī)制。
- (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.
請注意,您可以使用直接自我的塊保留周期不會發(fā)生蚂夕。因為YTKRequest將回調(diào)塊為零,所以塊將網(wǎng)絡(luò)請求完成后發(fā)布迅诬。
Besides the block callback, YTKRequest also support delegate callback method. The example is below:
除了塊回調(diào),YTKRequest也支持委托回調(diào)方法。下面的例子是:
- (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 驗證響應(yīng)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.
來自服務(wù)器的響應(yīng)JSON總不會是可信的婿牍〕薮客戶可能會崩潰,如果數(shù)據(jù)從服務(wù)器返回錯誤的格式。
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:
舉個例子,假設(shè)我們需要發(fā)送一個GET請求到http://www.yuantiku.com/iphone/users地址和一個名叫userId參數(shù)俏蛮。服務(wù)器將返回目標(biāo)用戶的信息,包括昵稱和水平撑蚌。我們將保證昵稱的響應(yīng)類型是字符串和水平數(shù)的類型。為了確保這一點,我們可以覆蓋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: 需要返回字符串?dāng)?shù)組:
- (id)jsonValidator {
return @[ [NSString class] ];
}
Here is one complex sample from our company: 這是一個復(fù)雜的樣品從我們的公司:
- (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地址睬棚。然后下面的代碼應(yīng)該是:
// 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 可恢復(fù)的下載
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.
如果你想使可恢復(fù)的下載,你只需要覆蓋resumableDownloadPath方法和提供一個臨時路徑保存half-downloaded數(shù)據(jù)第煮。
We can modify above example to support resumable downloading.
我們可以修改上面的例子來支持可恢復(fù)的下載。
@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 緩存響應(yīng)數(shù)據(jù)
We've implemented the GetUserInfoApi before, which is used for getting user information.
我們已經(jīng)實現(xiàn)了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.
我們可能想要緩存響應(yīng)包警。在接下來的例子中,我們覆蓋cacheTimeInSeconds方法,那么我們的API為指定的時間會自動緩存數(shù)據(jù)。如果緩存數(shù)據(jù)沒有過期,api的開始和startWithCompletionBlockWithSuccess將直接返回緩存的數(shù)據(jù)結(jié)果底靠。
@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.
緩存機(jī)制對控制器是透明的,這意味著請求調(diào)用者可能會調(diào)用請求的結(jié)果后沒有因為任何真正的網(wǎng)絡(luò)流量,只要其緩存的數(shù)據(jù)仍然有效害晦。
The above code samples are available in the YTKNetworkDemo project.
上面的代碼樣本YTKNetworkDemo項目中是可用的。