iOS開發(fā)-網(wǎng)絡(luò)-合理封裝請求接口無標題文章

轉(zhuǎn)載:http://www.fwqtg.net/ios%E5%BC%80%E5%8F%91-%E7%BD%91%E7%BB%9C-%E5%90%88%E7%90%86%E5%B0%81%E8%A3%85%E8%AF%B7%E6%B1%82%E6%8E%A5%E5%8F%A3.html?

概述

如今大多App都會與網(wǎng)絡(luò)打交道套蒂,作為開發(fā)者钞支,合理的對網(wǎng)絡(luò)后臺請求接口進行封裝十分重要。本文要介紹的就是一種常見的采用回調(diào)函數(shù)(方法)的網(wǎng)絡(luò)接口封裝操刀,也算的是一種構(gòu)架吧烁挟。

這個構(gòu)架主要的idea是這樣的,把所有的接口封裝成一個類骨坑,在工程中隨時可以調(diào)用撼嗓。并且利用代理Delegate構(gòu)建回調(diào)方法(callBack),工程中隨處可以通過回調(diào)方法監(jiān)聽網(wǎng)絡(luò)請求的反饋欢唾,也就是說且警,一旦得到了服務(wù)器反饋的數(shù)據(jù),回調(diào)函數(shù)中的代碼就(才)會被激活礁遣。網(wǎng)絡(luò)請求基于AFNetworking(AFNetworking斑芜,非常有名的網(wǎng)絡(luò)請求第三方類庫),請求均為異步祟霍。如此構(gòu)架杏头,非常靈活很容易擴展和復用。

講解

要想使用本文介紹的構(gòu)架沸呐,你首先需要掌握代理(Delegate)醇王,如果你不熟悉代理,這個構(gòu)架對你來說將會很不解垂谢。對于不熟悉代理的同學們厦画,建議

你們?nèi)タ匆幌沦Y料疮茄。網(wǎng)絡(luò)請求其實說白了就是和服務(wù)器做一個數(shù)據(jù)交互滥朱,App把請求數(shù)據(jù)發(fā)給服務(wù)器,服務(wù)器返回給App一個反饋數(shù)據(jù)力试。請先看一下這個構(gòu)架的

示意圖徙邻,如下:

如上圖,這個構(gòu)架的主要節(jié)點有三個畸裳,封裝網(wǎng)絡(luò)請求的類(接口類)缰犁、使用網(wǎng)絡(luò)請求的類(圖中的ViewController)、和服務(wù)器。

Ok~故事是這樣的帅容,一個夜黑風高的…醉醺醺ViewController走在湖邊颇象,為了找回被關(guān)在云端的Data,他苦練數(shù)載終于參透了《接口類》并徘,天地無情遣钳,今天是時候做個了斷了。

于是乎他從懷中拿出了傳說中的“接口類”麦乞,使用內(nèi)力蕴茴,實例化了一個接口類的對象,接著口中念出“接口類實例.delegate=self”,拔出利

劍在身旁實現(xiàn)了“接口類”中的一個代理方法。然后調(diào)用接口的方法衩藤,方法通過內(nèi)嵌的AFNetworking唯欣,向服務(wù)器發(fā)出了一道請求。又是一陣夜風吹過俏蛮,

三兩枯葉瑟瑟落下。ViewController酣意漸濃閉上了眼睛,現(xiàn)在他能做的唯有等待…

鏡頭一轉(zhuǎn)能扒,月色中,在天上辫狼,在云端的服務(wù)器初斑,ViewController剛才發(fā)出的請求正在興風作浪,云端值夜班的眾神絲毫不敢怠慢各個健步如飛膨处,從數(shù)據(jù)庫中搜索著能化解這道請求的神器见秤。

此時,ViewController困意漸濃真椿,眼皮似墜了千金重物鹃答,意識也漸漸模糊。突然云端顯出異像突硝,ViewController頓時醒了過

來测摔,隱約可以看到,云端有數(shù)據(jù)絲絲縷縷的流動解恰,而自己懷中的“接口類”內(nèi)嵌的AFNetworking也變得熾熱起來锋八,HTTP反饋block像是要爆炸

一樣的顫動著。ViewController豆大的汗珠從額頭滾下护盈,再也不能淡定挟纱,口中叨咕著,快了腐宋,快來了…

一個霹靂紊服,剛才用劍實現(xiàn)的代理方法金光一閃刺得ViewController捂住了雙眼檀轨。

一切都回歸安靜后,ViewController睜開眼睛欺嗤,發(fā)現(xiàn)Data安靜的躺在代理方法的里面…

代碼示例

下面通過一個例子参萄,來介紹一下。

打開Xcode我建了一個SingleViewApp煎饼,然后把AFNetworking加載進工程拧揽,如下圖:

我們?OpenWeatherMap提供的天氣預報的API作為例子,簡單地利用上述構(gòu)架腺占,做一個天氣預報的App

我們來看一下這個接口怎么用淤袜,很簡單:

例子:http://api.openweathermap.org/data/2.5/weather?q=beijing

參數(shù):q=城市名字

返回Json:

{"coord":{"lon":116.4,"lat":39.91},"sys":{"type":1,"id":7405,"message":0.013,"country":"CN","sunrise":1435870233,"sunset":1435924003},"weather":[{"id":800,"main":"Clear","description":"Sky is Clear","icon":"01d"}],"base":"stations","main":{"temp":305.43,"pressure":1008,"humidity":28,"temp_min":302.15,"temp_max":308.71},"visibility":10000,"wind":{"speed":2,"deg":0},"clouds":{"all":0},"dt":1435900364,"id":1816670,"name":"Beijing","cod":200}

為了簡單我們的Demo App就只顯示 天氣和溫度,UI如下圖:

簡單直觀衰伯,點擊不同城市名字命名的按鈕铡羡,在Label中顯示其天氣狀況,關(guān)于UI不是今天討論的重點意鲸,我們主要討論網(wǎng)絡(luò)和接口烦周。

現(xiàn)在開始重頭戲:接口類

新建一個類我把它命名為“Net”類,繼承NSObject怎顾,并導入”AFNetworking.h”頭文件:

////Net.h//NetInterface////Created by Oliver on 15/7/3.//#import#import"AFNetworking.h"@interfaceNet : NSObject@end

這個類就是我們一直提到的接口類读慎,我們要吧所有的網(wǎng)絡(luò)接口都寫到這個類里面。現(xiàn)在寫一個天氣預報接口作為例子槐雾。為天氣預報接口在Net類里聲明一個實例方法夭委,由于這個接口需要傳得參數(shù)只有一個城市名稱,在Net類的H文件所以方法聲明如下:

/**? *? 獲得某城市的天氣? *? *? @param cityName 城市名稱*/-(void)getWeatherInfoWithCity:(NSString *)cityName;

一起看起來都很美好對不對募强?那么現(xiàn)在我要提一點株灸,可能會被大家忽略的因素。由于我們實際開發(fā)的App調(diào)用接口的次數(shù)可能會很多擎值,而且調(diào)用接口的類也很多慌烧,所以,Net這個類將會被多次的實例化鸠儿,那么很有可能App的網(wǎng)絡(luò)層會變得很亂更有甚者會出Bug屹蚊。所以,像這樣的接口類进每,我們有必要將它做成單例的汹粤,整個App共享一個接口類的實例。Ok品追,下面就來介紹獲取單例的方法:

在H文件聲明獲取單例的方法:

/**? *? 獲取Net類的單例? *? *? @return Net類的單例 實例(對象)*/+(Net *)getInstance;

接下來我們在Net.m文件實現(xiàn)獲取單例方法:(因為所有的接口請求都是HPPT請求玄括,會用到AFNetworking的AFHTTPRequestOperationManager冯丙,所以我在getInstace方法里面把Manager也單例了)

#import"Net.h"__strongstaticAFHTTPRequestOperationManager *AFHTTPMgr; __strongstaticNet *NetInstance=nil;@implementationNet+(Net *)getInstance{staticdispatch_once_t onceToken;? ? dispatch_once(&onceToken,^{? ? ? ? NetInstance= [[Net alloc]init];//初始化實例//一下是AFHTTPOerrationManager的配置AFHTTPMgr=[AFHTTPRequestOperationManager manager];//申明返回的結(jié)果是json類型AFHTTPMgr.responseSerializer=[AFJSONResponseSerializer serializer];//申明請求的數(shù)據(jù)是json類型AFHTTPMgr.requestSerializer=[AFJSONRequestSerializer serializer];//如果報接受類型不一致請?zhí)鎿Q一致text/xml或別的//AFHTTPMgr.responseSerializer.acceptableContentTypes= [NSSet setWithObject:@"text/xml"];//設(shè)置超時時間AFHTTPMgr.requestSerializer.timeoutInterval=5;? ? });returnNetInstance; }@end

上面代碼中肉瓦,因為很變量的操作是在Block中做的遭京,而block中不能對block外的變量進行重新更改,所以在程序的實現(xiàn)之前泞莉,聲明了:

__strong static AFHTTPRequestOperationManager *AFHTTPMgr;

__strong static Net *NetInstance=nil;

以便在單例的Block里面對其進行更改哪雕。

接下啦,我們就可以繼續(xù)去實現(xiàn)接口的方法getWeatherInfoWithCity:

-(void)getWeatherInfoWithCity:(NSString *)cityName{//接口地址NSString *url=[NSString stringWithFormat:@"http://api.openweathermap.org/data/2.5/weather"];//參數(shù)NSDictionary *parameters=[[NSDictionary alloc]initWithObjectsAndKeys:cityName,@"q", nil];//發(fā)請求[AFHTTPMgr GET:url parameters:parameters success:^(AFHTTPRequestOperation *operation,idresponseObject) {//請求成功Block} failure:^(AFHTTPRequestOperation *operation, NSError *error) {//請求失敗Blick}]; }

如上代碼所示鲫趁,這就是我們獲取天氣預報的接口斯嚎,AFNetworking的請求成功和請求失敗的回調(diào)Block我們暫且空著,因為挨厚,我們要設(shè)置了Delegate再用堡僻。為什么我們要用代理而不是直接把想做的事情放在AFNetworking的Block里面呢?

答案其實顯而易見疫剃,Block是輕量級的代碼塊钉疫,雖然使用簡單,但是非常的封閉巢价,與外部(Block外)進行數(shù)據(jù)交換的能力非常的有限牲阁。比如我們天氣預報的例子,我們的ViewController類希望通過服務(wù)器返回的天氣信息壤躲,改變UILabel的信息城菊,而這個數(shù)據(jù)又在Net這個類的Block里面,沒辦法傳遞給ViewController碉克,這就讓局面變得非常尷尬凌唬。所以我們要使用代理Delegate。其實Delegate的核心的作用就是來實現(xiàn)類之間的數(shù)據(jù)傳遞÷┞螅現(xiàn)在請你法瑟,再次看一下上面的那張架構(gòu)示意圖,我想你會對其有更深的理解唁奢。

下面霎挟,聲明Net類的代理,H文件的代碼如下:

在導入頭文件聲明和@interface之間 用@protocol聲明代理

//Net.h//NetInterface#import#import"AFNetworking.h"http://代理@protocolNetDelegate /**? *? 代理回調(diào)方法? *? *? @param feedbackInfo 服務(wù)器返回的數(shù)據(jù)*/-(void)getWeatherInfoSuccessFeedback:(id)feedbackInfo;-(void)getWeatherInfoFailFeedback:(id)failInfo;@end@interfaceNet : NSObject? @property (nonatomic,strong)iddelegate;/**? *? 獲取Net類的單例? *? *? @return Net類的單例 實例(對象)*/+(Net *)getInstance;/**? *? 獲得某城市的天氣? *? *? @param cityName 城市名稱*/-(void)getWeatherInfoWithCity:(NSString *)cityName;@end

如上代碼麻掸,這是Net類的完整地H文件酥夭,我們在代理部分,聲明了兩個方法脊奋,一個請求成功熬北、一個請求失敗。在代理中申明的代理方法诚隙,我們不用去實現(xiàn)它讶隐,而是在M文件總直接使用它。如果自己要使用的代理我們需要將代理聲明為自己的成員變量:

@property (nonatomic,strong)iddelegate;

OK久又,現(xiàn)在讓我們回到getWeatherInfoWithCirt:方法巫延,在Block中使用代理方法效五。代碼如下:

-(void)getWeatherInfoWithCity:(NSString *)cityName{//接口地址NSString *url=[NSString stringWithFormat:@"http://api.openweathermap.org/data/2.5/weather"];//參數(shù)NSDictionary *parameters=[[NSDictionary alloc]initWithObjectsAndKeys:cityName,@"q", nil];//發(fā)請求[AFHTTPMgr GET:url parameters:parameters success:^(AFHTTPRequestOperation *operation,idresponseObject) {//請求成功Block//將返回數(shù)據(jù)傳入代理方法[self.delegategetWeatherInfoSuccessFeedback:responseObject];? ? } failure:^(AFHTTPRequestOperation *operation, NSError *error) {//請求失敗Blick//將錯誤信息傳入代理方法[self.delegategetWeatherInfoFailFeedback:error];? ? }]; }

OK, 如果你一路跟下來,恭喜你炉峰,你的方法類構(gòu)建完成了畏妖。你的每一個接口都可以按照以上的方式,寫成接口類的方法疼阔,然后用代理把它傳遞給其他類戒劫。

那么其他類怎么接受通過代理傳遞過來的數(shù)據(jù)呢?

打開ViewController,導入“Net.h”文件婆廊,在繼承聲明后添加實現(xiàn)代理迅细,如下代碼:

//ViewController.h//NetInterface#import#import"Net.h"@interfaceViewController : UIViewController @end

為了使用方便我添加了一個Net類的成員變量,KYNet:

@property Net *KYNet;

接下來我們要在M文件中使用接口嘍~~~代碼如下:

////ViewController.m//NetInterface#import"ViewController.h"@interfaceViewController ()@end@implementationViewController- (void)viewDidLoad {? ? [super viewDidLoad];? ? _KYNet=[Net getInstance];//得到單例

_KYNet.delegate=self; //將KYNet的代理與ViewController連接

}//北京按鈕- (IBAction)beijingTouched:(id)sender {? ? ? ? ? [_KYNet getWeatherInfoWithCity:@"Beijing"]; }//上海按鈕- (IBAction)shanghaiTouched:(id)sender {? ? [_KYNet getWeatherInfoWithCity:@"Shanghai"]; }@end

如上代碼淘邻,當我們按下按鈕疯攒,就會使用我們的接口類發(fā)送請求

慢著~怎么接收服務(wù)器反饋數(shù)據(jù)?列荔!

對了敬尺,下面我們通過實現(xiàn)Net的代理方法來接受處理數(shù)據(jù),并更新到UILabel上,在M文件實現(xiàn)贴浙,Delegate的兩個方法:

-(void)getWeatherInfoSuccessFeedback:(id)feedbackInfo{//當服務(wù)器返回成功數(shù)據(jù)后砂吞,下列代碼被激活NSLog(@"%@",[feedbackInfoclass]);? ? NSDictionary*dic=feedbackInfo;? ? NSArray*weather1=[dic objectForKey:@"weather"];? ? NSDictionary*main1=[dic objectForKey:@"main"];? ? NSDictionary*weather=[weather1 objectAtIndex:0];? ? NSString*temp=[NSString stringWithFormat:@"%@",[main1 objectForKey:@"temp"]];? ? NSString*weatherInfo=[NSString stringWithFormat:@"%@",[weather objectForKey:@"description"]];? ? ? _condition.text=weatherInfo;? ? _tem.text=temp; }-(void)getWeatherInfoFailFeedback:(id)failInfo{? ? NSLog(@"%@",failInfo); }

完活~

Hit Run~~~

總結(jié)

手指頭敲酸了…寫博客比寫代碼累多啦TT。Ok總結(jié)一下崎溃。

本文的核心思想是把所有的網(wǎng)路請求封裝成一個類蜻直,向外部提供各個接口的請求方法,以便使用者發(fā)送請求袁串;而當服務(wù)器返回反饋數(shù)據(jù)后概而,外部通過實現(xiàn)代理方法來獲得數(shù)據(jù)。這樣的架構(gòu)的好處是非常靈活囱修,低耦合赎瑰,擴展簡單。實現(xiàn)的代理方法會在服務(wù)器返回數(shù)據(jù)的是時候自動被調(diào)用破镰,結(jié)合異步的AFNetworking餐曼,開發(fā)者不用去擔心線程問題。這樣一來鲜漩,程序主線的邏輯設(shè)計也會變得很簡單源譬。用此構(gòu)架封裝好的類,可以輕松的打包成SDK給別人使用孕似。

謝謝大家踩娘,希望你們有所收獲,一篇文章花了我整整一天時間喉祭,如果對你有所幫助請幫忙點贊养渴。如有問題雷绢,歡迎評論。若要轉(zhuǎn)載厚脉,請注明出處习寸。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末胶惰,一起剝皮案震驚了整個濱河市傻工,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌孵滞,老刑警劉巖中捆,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異坊饶,居然都是意外死亡泄伪,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門匿级,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蟋滴,“玉大人,你說我怎么就攤上這事痘绎〗蚝” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵孤页,是天一觀的道長尔苦。 經(jīng)常有香客問我,道長行施,這世上最難降的妖魔是什么允坚? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮蛾号,結(jié)果婚禮上稠项,老公的妹妹穿的比我還像新娘。我一直安慰自己鲜结,他們只是感情好皿渗,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著轻腺,像睡著了一般乐疆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贬养,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天挤土,我揣著相機與錄音,去河邊找鬼误算。 笑死仰美,一個胖子當著我的面吹牛迷殿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播咖杂,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼庆寺,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了诉字?” 一聲冷哼從身側(cè)響起懦尝,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎壤圃,沒想到半個月后陵霉,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡伍绳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年踊挠,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片冲杀。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡效床,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出权谁,到底是詐尸還是另有隱情剩檀,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布闯传,位于F島的核電站谨朝,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏甥绿。R本人自食惡果不足惜字币,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望共缕。 院中可真熱鬧洗出,春花似錦、人聲如沸图谷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽便贵。三九已至菠镇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間承璃,已是汗流浹背利耍。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人隘梨。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓程癌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親轴猎。 傳聞我的和親對象是個殘疾皇子嵌莉,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 概述如今大多App都會與網(wǎng)絡(luò)打交道,作為開發(fā)者捻脖,合理的對網(wǎng)絡(luò)后臺請求接口進行封裝十分重要锐峭。本文要介紹的就是一種常見...
    坤哥lqk閱讀 881評論 0 1
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,139評論 30 470
  • iOS網(wǎng)絡(luò)架構(gòu)討論梳理整理中。郎仆。只祠。 其實如果沒有APIManager這一層是沒法使用delegate的兜蠕,畢竟多個單...
    yhtang閱讀 5,188評論 1 23
  • 來自國外網(wǎng)站的30條馬云名言熊杨,讓你看到中西文化的異同曙旭。從中也能看出,馬云是如何打動外國人的晶府。 If you are...
    核聚閱讀 1,597評論 0 2
  • 不知你是否觀察過川陆,從小時候到現(xiàn)在剂习,不論上學還是工作總有一些很優(yōu)秀的人,他們可以把自己的學習顧好较沪、又可以和別人的關(guān)系...
    把快樂帶給你閱讀 363評論 2 8