iOS WebServiceFramework網路服務架構淺解

來源:互聯網
上載者:User

標籤:des   style   blog   http   io   ar   color   os   使用   

  不知不覺畢業後也工作了快半年了,時光荏苒總覺得若再不寫點什麼,留下點痕迹,我都快把自己遺忘了。從接觸iOS到現在初略算有一年多了吧,我很想把自己所看所想所領悟的一些技巧給大家分享,但自身開發經驗也不算成熟,今天厚一厚臉皮,寫自己的第一篇部落格,我想只要不誤人子弟,這次就算我贏了吧。下面進入正題——構建iOS的網路業務請求架構。

  網路服務幾乎是每一款成功APP的必備條件,開啟你手機你會發現裡面不用連網的應用數量十隻手指可以數出來,就算是一些以獨特技術切入市場的APP如美顏相機,都至少加入了分享功能。下面我先做下簡單的回顧兼掃盲。

  蘋果定義了NSConnection 這個類來專門處理網路請求,並且這個類有兩種用法來滿足開發人員需求。

用法一,同步請求  

 //NSURLConnection.h

 @interface NSURLConnection (NSURLConnectionSynchronousLoading)

  + (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error;

 @end

//**.mNSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:response error:error];

這種用法比較少人使用,因為他無法捕捉傳輸過程的內容,並且需要在子線程中使用,不然將會卡住主線程的UI繪製,直到sendSynchronousRequest返回data,但勝在簡單易用,一目瞭然。

用法二,非同步請求  

//NSURLConnection.h

 @interface NSURLConnection : NSObject

 - (instancetype)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately; - (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode; - (void)start;
@end
//**.m
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO]; 
[connection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
[connection start];

相比第一種用法,第二種頓時讓人云裡霧裡,特別nsrunloop更讓人疑問,另外,上面的代碼僅僅是開始請求部分,資料接收部分的代碼還沒貼出來。

細心的人注意到,在.m檔案中,NSConnection初始化時傳入了一個delegate,是的,資料便是通過NSURLConnectionDataDelegate的回調來處理的。

//NSURLConnection.h
@protocol NSURLConnectionDataDelegate <NSURLConnectionDelegate>@optional
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;@end

為了不讓其他函數擾亂了大家的實現,這裡我只貼出跟本文有關的函數,從字面上大家都能知道這他們的作用了,didReceiveData會攜帶著請求下來的資料data多次回調,didFinishLoading是在請求結束後調用,另外還有一個didFailWithError在請求失敗是調用,只不錯他是老爸NSURLConnectionDelegate的內容。

下面我們回到第二種用法的.m檔案,這裡面涉及到runloop的執行機制,我在這裡只解釋為什麼要這樣設定。

Runloop有五種運行模式,這裡我只說三種:

1,NSDefaultRunLoopMode: 預設的運行模式,除了NSConnection對象的事件;

2,UITrackingRunLoopMode: 用於跟蹤觸摸事件觸發的模式(例如UIScrollView上下滾動),主線程當觸摸事件觸發時會設定為這個模式;

3,NSRunLoopCommonModes: 是一組常用的模式集合,簡單來將就是模式集合,既然是集合,當然包括上面的兩種模式。

預設情況下NSURLConnection,NSTimer都是運行1模式下,那麼問題來了,假如這個時候使用者刷一下螢幕,此時切換為模式2,而這時候剛好有資料請求下來,那麼就悲劇了,didReceiveData不會回調。(如果NSTimer涉及精密的資料計算,這裡也要注意下)解決辦法就是替換成NSRunLoopCommonModes。

著名的SDWebImage在網路非同步請求圖片時也是使用第二種方法,個人覺得這種方法相當高效,在不建立新線程的情況下,依靠runloop來監聽網路請求資料,如果同學們還是有點淩亂,不妨試下將NSURLConnection替換成NSTimer這樣,其實原理都差不多。

另外這裡有一點NSConnection在初始化的時候要注意startImmediately:不能設定為YES,如果你設定為YES,後在設定runloopmode是無效的。

現在理解了網路請求最具高效的方案(個人認為。。。),有沒有感覺這些代理什麼挺繁瑣的,而一個APP不可能只有一個網路請求介面,這時候我們就需要一個管理者的角色,我們暫時將它命名為HttpManager。一個manager統領著一群connection,這時候你發現問題又來了,connection從外表上看長得都一樣,沒有可以標記的東西,於是,我們給他造個子類MyURLConnection 並且加多一個tag欄位,來互相辨認。:

 

有了tag後,tag用什麼來裝填好呢,對tag唯一的要求就是不重複,這裡我就直接使用url來做tag,因為除非奇葩需求,否側url重複請求確實沒有必要。

在didReceivaData中,_dataTagMap跟據tag,追加資料;

在sendHttpRequestWithUrl中,先檢查_connectionTagMap中是否已經有以該url為key的對象了,有就說明已經這條請求,這條請求可以丟棄了。沒有就new一個MyURLConnection 並將url作為tag,最後以url為key ,myconnection為value填入_connectionTagMap中;

在didFinishLoading中,根據connect的tag值,將對應的connection從_dataTagMap中提出來並發給對應的Model層處理,並從_dataTagMap和_connectionTagMap移除相應項;

好像聽起來很簡單的樣子,實際上,也很簡單。。。這裡的發給Model層可能有些同學有迷糊了,什麼叫發?大家注意到前面_connectionTagMap如果發現有重複直接丟棄即return,所以這要求HttpManager和與之互動的類必須低耦合,所以這裡的發意思是指使用通知

 [[NSNotificationCenter defaultCenter] postNotificationName:KHTTPMgrNotificationSendRequestCompleted object:self userInfo:info];

info其實就一個NSDictionary,裡面你想裝什麼就裝什麼,用過都知道。

今天先到這裡吧,本來想寫兩種請求架構對比,結果唯寫了一種也唯寫了一半,只好下周末再補上對應的網路業務Model層以及另外一種請求架構了。

iOS WebServiceFramework網路服務架構淺解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.