在使用網(wǎng)絡(luò)請求的過程中,可以使用系統(tǒng)的框架、ASI、AF、MK等等,但是如果需要更換項目的網(wǎng)絡(luò)請求框架(比如,項目之前用的ASI的框架,現(xiàn)在需要更換為AF),那么這將是一個浩大的工程。項目初期,怎么搭建網(wǎng)絡(luò)請求框架,才可以讓修改網(wǎng)絡(luò)請求的工程量減到最小呢,這是我們今天要說的問題。
封裝的網(wǎng)絡(luò)請求框架一共三層:
第三層:ASI、AF或者其他網(wǎng)絡(luò)請求方式。
第二層:第二層分有基類與類目(Category)構(gòu)成,基類用于配置共有參數(shù)與發(fā)起請求,分類則是為了團(tuán)隊開發(fā)與結(jié)構(gòu)清晰。
第一層:業(yè)務(wù)層,比如一個登錄、注冊操作,需要從界面上獲得參數(shù),并配置回調(diào)。

1. 首先需要找到在這幾種網(wǎng)絡(luò)請求中,最大的不同是什么?
ASI、AF在使用時,最大的不同就是他們的初始化方法,所以我們首先要將這一層封裝出來,作為框架第二層的基類?;愔羞M(jìn)行共有參數(shù)的配置以及發(fā)起請求,也可以有多種發(fā)起請求的方法。比如說項目中需要用到GET、POST同步異步請求,都可以在基類中配置并公開。
下面的代碼為,初始化AFNetworking(第三層),配置參數(shù)并發(fā)起POST異步請求的基類方法:
+ (void)sendPostRequestWithMethod:(NSString *)method parameters:(NSDictionary *)parameters callback:(Callback)callback {
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer.acceptableContentTypes = [NSSetsetWithObject:@"text/html"];
[manager POST:Base_Url(method) parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
if (callback) {
callback(1, nil);
return;
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (callback) {
callback(0, error);
return ;
}
}];
}
在這個類中將該方法公開,那么其他類目(Category)可以通過它,發(fā)起請求。
2. 每一個網(wǎng)絡(luò)請求的參數(shù)與請求地址配置
在項目中,我們可能會發(fā)起上百個網(wǎng)絡(luò)請求,每一個網(wǎng)絡(luò)請求的地址都不同,參數(shù)也不同,接口對參數(shù)格式的要求也就不相同。比如,登錄操作,可能需要對密碼進(jìn)行加密;一串?dāng)?shù)字可能需要用’-‘進(jìn)行拼接等等。那么這個參數(shù)在View層中配置好不好呢,當(dāng)然也可以,但是不夠清晰,東一個西一個,后臺修改了參數(shù)格式以后,要到界面代碼中找很久。那么,我給出的解決辦法是:
將參數(shù)與地址配置在第二層的類目中,View層只需要引入類目頭文件,傳入未經(jīng)過處理的參數(shù),然后由類目中的方法來進(jìn)行配置即可。
代碼如下:
@implementation RequestBase (LoginRequest)
/**
* 配置登錄參數(shù)與請求地址,向第三層發(fā)起POST異步登錄請求
*
* @param username 用戶名
* @param password 未進(jìn)行加密處理的密碼
* @param callback 完成網(wǎng)絡(luò)請求的回調(diào)
*/
+ (void)sendLoginRequestWithUsername:(NSString *)username password:(NSString *)password callback:(Callback)callback {
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
[parameters setObject:[NSString stringWithFormat:@"username:%@", username] forKey:@"username"];
[parameters setObject:password forKey:@"password"];
[RequestBase sendGetRequestWithMethod:@"login" parameters:parameters callback:callback];
}
@end
每一個請求對應(yīng)一個單獨(dú)的方法,參數(shù)與地址的配置清晰明了。
3. View層發(fā)起網(wǎng)絡(luò)請求與回調(diào)處理(登錄為例)
當(dāng)?shù)卿洶粹o點(diǎn)擊時進(jìn)行網(wǎng)絡(luò)請求
/**
* 登錄按鈕點(diǎn)擊響應(yīng)事件
*
* @param sender 登錄按鈕
*/
- (void)loginButtonPressed:(UIButton *)sender {
// 發(fā)起登錄請求,將參數(shù)傳至第二層,進(jìn)行詳細(xì)配置(如password的加密等操作)
[RequestBase sendLoginRequestWithUsername:@"Jane Doe" password:@"password" callback:^(NSError *error, NSMutableDictionary *result) {
// 判斷回調(diào)是否失敗或者返回值是否為字典(也可以將判斷步驟放到第二層基類中)
if (!error && [result isKindOfClass:[NSDictionary class]]) {
NSLog(@"登錄成功");
}
}];
}
那么到此,三層網(wǎng)絡(luò)請求的框架已經(jīng)搭建完畢了,結(jié)構(gòu)很清晰,用法也很簡單。如果再遇到需要更換網(wǎng)絡(luò)請求的情況,僅需要將第三層替換掉,第二層基類中,更換初始化網(wǎng)絡(luò)請求方式即可,其余代碼完全不用替換。
如果還不清楚如何封裝系統(tǒng)的網(wǎng)絡(luò)請求,可閱讀: