對於AlamoFire幾點思考

来源:http://www.cnblogs.com/8hao/archive/2016/03/02/5234934.html

本文由CocoaChina--BYB_1132(論壇ID)翻譯 原文:Thoughts On AlamoFire--Swift’s AFNetworking Implementation HTTP協議就是現代開發的同義詞,對於有經驗的iOS開發者來說, 熟悉並儘可能使用這些流行的協議是日常工作的基礎


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

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

HTTP協議就是現代開發的同義詞,對於有經驗的iOS開發者來說, 熟悉並儘可能使用這些流行的協議是日常工作的基礎。

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

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

基礎

Alamofire的核心主要是試圖簡化iOS中HTTP網路連接, 它通過使用NSURLSession以及Foundation URL Loading System來創建一個Swift本地的網路訪問介面,從而實現令人難以置信效率的任務。

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

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

例如,通過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行業人員進入!


您的分享是我們最大的動力!

更多相關文章
  • 這是一張QQ空間說說詳情的截圖。 分析: 1、點擊右上角三個點的圖標,在界面底部彈出一個區域,這個區域有一些按鈕提供給我們操作 2、當該區域出現的時候,詳情界面便灰了,也說成透明度變化了 3、當任意選了一個按鈕或者點擊了該區域以外的部分,該區域消失,灰色界面變回亮白色,並執行點擊的按鈕對應的操作 顯
  • 這篇文章主要介紹一些小細節的優化技巧,當這些小技巧綜合使用起來的時候,對於整個App的性能提升還是有作用的,只是不能較大幅度的提升性能而已。選擇合適的演算法與數據結構才應該是你首要考慮的因素,在這篇文章中不會涉及這方面。你應該使用這篇文章中的小技巧作為平時寫代碼的習慣,這樣能夠提升代碼的效率。 通常來
  • 開發中遇到的問題:要實現一個button初始為不可點擊,於是在配置文件中設置了android:clickable="false"運行後發現還是可以點擊,於是寫在了Activity中:btn.setClickable(false);發現還是可以點擊,在網上查資料說android setClickabl
  • 轉載博客:http://blog.csdn.net/i_lovefish/article/details/17719081 以下為異常捕捉處理代碼: import java.io.BufferedReader; import java.io.File; import java.io.FileInpu
  • 分類:C#、Android、VS2015; 創建日期:2016-03-04 一、簡介 目前,基於位置的服務發展迅速,已涉及到商務、醫療、定位、追蹤、敏感區域警告、工作和生活等各個方面。定位服務融合了GPS定位、移動通信、導航等多種技術,從而獲取用戶終端設備的位置信息,為移動用戶提供了與空間位置相關的...
一周排行
  • 前言 上篇我們實現了ModBusTcp協議的客戶端讀寫,可是在很多時候編寫業務代碼之前是沒有現場環境的。總不能在客戶現場去寫代碼,或是蒙著眼睛寫然後求神拜佛不出錯,又或是在辦公室部署一套硬體環境。怎麼說都感覺不太合適,如果我們能用軟體模擬模擬硬體那不就完美了,以後有各種不同的硬體協議介面都模擬出來, ...
  • 1. 為什麼需要設計一個狀態按鈕 "OnePomodoro" 應用里有個按鈕用來控制計時器的啟動/停止,本來這應該是一個包含“已啟動”和“已停止”兩種狀態的按鈕,但我以前在WPF和UWP上做過太多StateButton、ProgressButton之類的東西,已經厭倦了這種控制項,所以我在 應用里只是 ...
  • 場景 Winforn中設置ZedGraph曲線圖的屬性、坐標軸屬性、刻度屬性: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/100112573 在對ZedGraph進行曲線添加時,如果需要添加大量曲線,那麼最多可以添加多少條曲線 ...
  • 場景 有一個對象的list,每個對象有唯一的屬性Id,並且是從1遞增,現在要根據此Id屬性進行截取。 其中DataTreeNode 實現 Global.Instance.PrepareCompareDataInOne = Global.Instance.PrepareCompareDataInOne ...
  • IM SDK API 概述 https://cloud.tencent.com/document/product/269/33543 ...
  • 最近遇到一個使用try-catch異常捕獲後記錄一下日誌,然後再拋出該異常後,異常堆棧里無法顯示準確的堆棧地址的問題? 其實以前也遇到過類似問題,沒有重視,這次好好研究了下,並上度娘上找了找其他道友的文章一起看了,發現處理方式的不同的確會有影響!下麵會詳細介紹: 推薦使用:原始異常拋出寫法... ...
  • 遇到這個問題的最大可能是:aspx頁面存在bug。 比如說我的主頁是從項目里的別的頁面複製過來的,但是少複製了一些引用,頁面就存在bug,導致aspx.designer.cs沒有自動生成代碼。 解決方案:解決aspx頁面存在的bug,再ctrl+s保存一下就行。 ...
  • 恢復內容開始 參考:https://www.cnblogs.com/vipstone/p/9275256.html RabbitMQ簡介 在介紹RabbitMQ之前實現要介紹一下MQ,MQ是什麼? MQ全稱是Message Queue,可以理解為消息隊列的意思,簡單來說就是消息以管道的方式進行傳遞。 ...
  • .NET CORE 3.0發佈已久,而令人興奮的是,終於,.NET版Aspose Words可以在.NET CORE 3.0中使用啦!近日,Aspose Words For .NET更新到了v19.11版,在Word文檔中添加Web擴展元素,設置水平規則的格式,併在.NET Core 3.0中使用A ...
  • Microsoft Office是微軟公司的一個文字處理器應用程式,作為辦公軟體必不可少的神器之一,其中Word、Excel、PDF是日常工作中常用的文檔管理工具。目前,Aspose系列和Spire系列是文檔管理開發API中非常受歡迎的兩個系列產品。今天我們來比較兩個系列旗下的PDF管理控制項Aspo ...
x