Alamofire 源码学习(二)- 源文件与接口


 原文链接     by: song4

本文所使用的 Almofire 库的版本是 3.4.1。

源文件

Alamofire 的源文件不多,按照功能职责分为 Core 和 Features 两组,再加上一个提供公有接口的 Alamofire.swift 文件:

Source/
├── Alamofire.swift                       // 定义了 Alamofire 的公有接口
|
├── Core/
|   ├── Error.swift                       // 定义了一组错误码
|   ├── Manager.swift                     // 负责创建请求
|   ├── Notifications.swift               // 定义了一组通知名称,Alamofire 会在特定时刻发布这些通知
|   ├── ParameterEncoding.swift           // 定义了一组参数编码方案
|   ├── Request.swift                     // 可以认为是对 NSURLRequest 的封装
|   ├── Response.swift                    // 可以认为是对 NSURLResponse 的封装
|   └── Result.swift                      // 返回值的抽象
|
└── Features/
    ├── Download.swift                    // 处理下载任务
    ├── MultipartFormData.swift           // multipart/form-data 的抽象
    ├── NetworkReachabilityManager.swift  // 网络联通性指示器
    ├── ResponseSerialization.swift       // 对返回值进行序列化
    ├── ServerTrustPolicy.swift           // 定义了一组主机信任策略
    ├── Stream.swift                      // 处理流式任务
    ├── Timeline.swift                    // 对请求的生命周期进行计时
    ├── Upload.swift                      // 处理上传任务
    └── Validation.swift                  // 对返回值进行验证

下面的(并不十分准确的)示意图可以帮助理解 Alamofire 的内部机制:


Internal Process

接口

新开始阅读一个库的源代码时,往往不容易找到合理的入口点。考察这个库的公有接口可能是一个很好的起点。首先,我们可以借此建立对该库的直观认识(可能比较浅显,不过现阶段足够了);然后,循着这些接口我们可以由浅入深,抽丝剥茧,逐渐全盘理解该库的运作方式。总结来说,Alamofire 所提供的公有接口分为这几大类:建立请求,处理返回,认证身份,设置请求头部和设置请求参数。

创建请求

根据不同的目的,请求可以分为三种:普通请求,下载请求,上传请求。

创建一个普通请求:

Alamofire.request(.GET, “https://httpbin.org/get”)

创建一个下载请求:

Alamofire.download(.GET, “https://httpbin.org/stream/100”)

创建一个上传请求:

let fileURL = NSBundle.mainBundle().URLForResource(“Default”, withExtension: “png”)
Alamofire.upload(.POST, “https://httpbin.org/post”, file: fileURL)

请求的第一个参数是一个枚举类型,其定义如下:

public enum Method: String {
    case OPTIONS, GET, HEAD, POST, PUT, PATCH, DELETE, TRACE, CONNECT
}

处理返回

Alamofire 的链式调用机制帮助我们写出简洁的代码。例如,我们可以将创建请求和处理请求返回的代码写在一条语句里面:

Alamofire.request(.GET, "https://httpbin.org/get")
         .response { request, response, data, error in
             print(request)
             print(response)
             print(data)
             print(error)
          }

如果你希望 Alamofire 对返回值进行序列化处理,可以使用下面这些变体方法。

返回 NSData 类型的数据:

Alamofire.request(.GET, "https://httpbin.org/get")
         .responseData { response in
             print(response.request)
             print(response.response)
             print(response.result)
          }

返回 String 类型的数据:

Alamofire.request(.GET, "https://httpbin.org/get")
         .validate()
         .responseString { response in
             print("Success: \(response.result.isSuccess)")
             print("Response String: \(response.result.value)")
         }

返回 JSON 类型的数据:

Alamofire.request(.GET, "https://httpbin.org/get")
         .responseJSON { response in
             debugPrint(response)
         }

认证身份

使用 HTTP 基本认证

let user = "user"
let password = "password"

Alamofire.request(.GET, "https://httpbin.org/basic-auth/\(user)/\(password)")
         .authenticate(user: user, password: password)
         .responseJSON { response in
             debugPrint(response)
         }

使用 NSURLCredential

let user = "user"
let password = "password"

let credential = NSURLCredential(user: user, password: password, persistence: .ForSession)

Alamofire.request(.GET, "https://httpbin.org/basic-auth/\(user)/\(password)")
         .authenticate(usingCredential: credential)
         .responseJSON { response in
             debugPrint(response)
         }

设置请求头部

let headers = [
    "Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==",
    "Accept": "application/json"
]

Alamofire.request(.GET, "https://httpbin.org/get", headers: headers)
         .responseJSON { response in
             debugPrint(response)
         }

设置请求参数

带有 URL-Encoded 参数的 GET 请求:

Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"])
// https://httpbin.org/get?foo=bar

带有 URL-Encoded 参数的 POST 请求:

let parameters = [
    "foo": "bar",
    "baz": ["a", 1],
    "qux": [
        "x": 1,
        "y": 2,
        "z": 3
    ]
]

Alamofire.request(.POST, "https://httpbin.org/post", parameters: parameters)
// HTTP body: foo=bar&baz[]=a&baz[]=1&qux[x]=1&qux[y]=2&qux[z]=3

带有 JSON 参数的 POST 请求:

let parameters = [
    "foo": [1,2,3],
    "bar": [
        "baz": "qux"
    ]
]

Alamofire.request(.POST, "https://httpbin.org/post", parameters: parameters, encoding: .JSON)
// HTTP body: {"foo": [1, 2, 3], "bar": {"baz": "qux"}}

(未完)

相关代码:

Alamofire