對於AlamoFire幾點思考

本文由CocoaChina--BYB_1132(論壇ID)翻譯php

原文:Thoughts On AlamoFire--Swift’s AFNetworking Implementationhtml

HTTP協議就是現代開發的同義詞,對於有經驗的iOS開發者來講, 熟悉並儘量使用這些流行的協議是平常工做的基礎。ios

不出意料,iOS 應用在這一點上沒有什麼不一樣,成千上萬的app和工程師都依靠廣受歡迎的AFNetworking 庫實現與服務器的交互,JSON解析, 以及提供佔位符圖片等多個功能。程序員

簡言之,作到這些並不容易。這篇文章中咱們了要解的是Alamofire庫。編程

基礎json

Alamofire的核心主要是試圖簡化iOS中HTTP網絡鏈接, 它經過使用NSURLSession以及Foundation URL Loading System來建立一個Swift本地的網絡訪問接口,從而實現使人難以置信效率的任務。swift

Swift放棄了代理模式取而代之的使用了回調。對於我而言,我喜歡這個選擇。然而基礎承諾機制模式(promise-based patterns)也能起到必定做用, 它們也隱藏了一些壞代碼味道,對於一些人有點太神奇了。api

進一步看,它是異步實現的。你也許據說過,可是在主線程上執行網絡調用並非一個好主意,不過Alamofire採用了許多創造性的最優方法。promise

例如,經過NSURLCache處理緩存來阻止沒必要要的訪問請求。另外,若是HTTP狀態碼在可接受的範圍內(200-300),就能夠利用其豐富的鏈路模式經過少許代碼去作大量有意義的工做。緩存

歷史總在重複

Alamofire 也承續了AFNetworing使用者所熟悉的模式,一些處理方法也不一樣於它的前身,主要由於Alamofire是爲了Swift而建立的。

例如, AFNetworking 調用子類AFHTTPSessionManager來使用每一個API。也有例外,好比用NSURLSession替換NSURLConection。

Alamofire 經過遵照URLRequestConvertible協議建立一個路由Router來調用了相似的方法, 在底層,Alamofire 使用單例模式來建立在 NSURLSessionConfiguration.的頂層

初體驗 

咱們開始吧

1
2
3
Alamofire.request(.GET, 「http: //www.telize.com/jsonip?callback=getip").response {(request, response, data, error) in
     println(request + response + error)
}

像AFNetworking 和其餘的HTTP網絡庫同樣,Alamofire提供了簡單、易用的方法來快速隨性的使用網絡請求。這種特定的網絡GET請求會返回一個請求對象,這個對象能夠依附實現全部的HTTP過程的方法。

在Alamofire中,默認的行爲規範是從服務器響應積累到的NSData(數據),我經過一個閉包來連接一個響應處理程序來解析響應,或者希望對任何錯誤的響應不會發生在請求過程當中。

  • 響應

響應經過HTTP用不一樣的形式顯現,最受青睞的毫無疑問是JSON, JSON是XML的衍生品,相對XML更年輕更健壯。Alamofire對JSON型數據很友好。

1
2
3
Alamofire.request(.GET, 「http: //httpbin.org/get").responseJSON {(request, response, JSON, error) in
     println(JSON)
}

有一系列簡單的JSON字符串做爲指定的響應返回數據

咱們繼續

在Alamofire中, 連接在其框架的使用中很底層, 每當想到在OC中用方括號去定義類,讓人或高興或無奈。

Swift 像其餘大多數高級語言同樣, 經過簡單的"."來調用函數, Alamofire 能夠管理不少響應處理程序,並且一旦服務器返回響應它都會異步執行。 

和往常同樣, 看示例最可靠

1
2
3
4
5
6
7
8
9
Alamofire.request(.GET, 「http: //httpbin.org/get")
     .authenticate(HTTPBasic: user, password: password)
     .progress { (bytesRead, totalBytesRead, totalBytesExpectedToRead)  in
     println(totalBytesRead)
}.responseJSON { (request, response, JSON, error)  in
     println(JSON)
}.responseString { (request, response, string, error)  in
     println(string)
}

參數

固然, 若是HTTP網絡請求缺乏了POST請求或查詢指定的訪問請求的能力就沒那麼使人期待了。

1
Alamofire.request(.GET,  "http://httpbin.org/get" , parameters: [ "key" "value" ])

在Alamofire須要內嵌一個包含參數的一個字典, 若是你不指向特定的參數, 將傳入nil。對於編碼來講也是同樣的, 在網絡請求函數這是第四個參數.

枚舉

若是有人已經使用過swift, 它們可能發現枚舉在Swift 中是如此的好用。在 Objective-C中,即便有現代化的NS_ENUM,它仍然只是容許定義整數聲明。

Swift 還有不少小技巧

Alamofire充分擁有這些技巧, 所以在一個HTTP通訊中全部的編碼參數邏輯都是用參數編碼(ParameterEncoding)枚舉實現, 全部的HTTP verbs都以 RFC 2616 §9 定義, 以下:

1
2
3
4
5
6
7
8
9
10
11
12
public enum Method: String
{
     case  OPTIONS = 「OPTIONS」
     case  GET = 「GET」
     case  HEAD = 「HEAD」
     case  POST = 「POST」
     case  PUT = 「PUT」
     case  PATCH = 「PATCH」
     case  DELETE = 「DELETE」
     case  TRACE = 「TRACE」
     case  CONNECT = 「CONNECT」
}

同時,若是你好奇Swift枚舉強大的功能, 免費下載 swift starter guide。請原諒我作的這個小廣告。

路由

建立一個網絡訪問路由是實現的關鍵, 在這裏將定義一些共同的用於同一個 API 的端點, 經過一個遵循URLRequestConvertible的枚舉來建立一個路由。

當一個枚舉遵循URLRequestConvertible時, 它須要包含一個叫作URLRequest的變量, 這個變量必須是NSURLRequest類型.

對於HTTP網絡庫的一般作法發生在這裏, 使用者極大可能定義一個靜態字符串來表明一個基礎的URL以及API key/consumer secret.

記住,在現實世界中最好不要將這些內容放到源代碼周圍。我我的選擇plist文件。

在任何狀況下……

工做流以下:

  • 定義一個基本的URL

  • 經過在枚舉中的case語句定義端口(例如 Users, Comments等等)

  • URLRequest初始化並經過一個跟蹤閉包設置。在閉包中, 增長參數並構造端點。

  • URL、URLRequest 和編碼都佔一個徹底的網絡請求發送到服務器 

多讀幾遍這個, 首先, 我認爲這點有些不合理---一個函數實現過多的功能

在實踐中,它運做得很好:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
enum APIRouter: URLRequestConvertible
{
     static let BASE_URL =  //base url
     static let API_KEY =  //api key, consumer secret for OAuth, etc
     
     case  User(Int)
     case  ProfilePicture(Int, Size)
     case  Likes(Int, Int)
  
     var  URLRequest: NSURLRequest
     {
         let (path: String, parameters: [String: AnyObject]) =
         {
             switch  self
             {
                  case  .User (let page):
                      let params = [] //Provide params
                      return  (「/user」, params)
                  case  .ProfilePicture(let id, let size): 
                      var  params = [] 
                      return  (「/profilepictures/\(id)」, params) 
                  case  .Likes(let id, let commentsPage): 
                      var  params = []  
                      return  (「/likes/\(id)/user」, params)
             }
         }()
  
         let URL = NSURL(string: APIRouter.BASE_URL)
         let URLRequest = NSURLRequest(URL:URL!.URLByAppendingPathComponent(path))
         let encoding = Alamofire.ParameterEncoding.URL
         return  encoding.encode(URLRequest, parameters: parameters).0
     }
}

一個強有力的例子, 可是我選擇把代碼展現的更形象些。

豐富的功能

Alamofire有許多讓程序猿信服去使用它的理由。在iOS開發中,使用NURLSession是HTTP網絡的將來趨勢, 相比NSURLConnection來講,它的功能更加豐富: 

  • 後臺上傳和下載

  • 暫停以及從新開始網絡操做的能力

  • 可配置的容器(Container)

  • 子類和私有存儲

  • 改進的認證處理

  • 對每一個基礎鏈接進行身份驗證

  • 多種代理模式--NSURLConnection擁有異步代碼塊的基本方法, 可是不能用它們的代理,NSURLSession具備一種混合型的方法。

我認爲你們都贊成這是正確的選擇, 若是有人對AFNetworking 能作而Alamofire不能作的感興趣的話,那麼有如下幾點:

  • UIKit 擴展

  • TLS驗證

  • NSOperation/NSURLConnection/AFURLConnectionOperation調用

  • 可達性(Reachability)

  • 多重HTTP網絡請求構架

根據使用狀況決定, 須要使用這些特色的要麼是破壞遊戲規則的人,要麼是不在意的人。

總結

在這一點上,部分工程師爭論認爲NSURLSession讓AFNetworking變成了一個華麗的封裝。這可能在某種程度上是正確的,但即便如此--這是一件壞事嗎?

它在簡化和抽象方面作的很好,雖然它不包含AFNetworking能夠作的全部功能,可是這是 Swift 中 HTTP 網絡的一個良好開端。

問啊-一鍵呼叫程序員答題神器,牛人一對一服務,開發者編程必備官方網站:www.wenaaa.com

QQ羣290551701 彙集不少互聯網精英,技術總監,架構師,項目經理!開源技術研究,歡迎業內人士,大牛及新手有志於從事IT行業人員進入!

相關文章
相關標籤/搜索