本文由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须要内嵌一个包含参数的一个字典, 若是你不指向特定的参数, 将传入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行业人员进入!