1. 程式人生 > 其它 >Alamofire4.x開原始碼分析(二)請求引數和編碼

Alamofire4.x開原始碼分析(二)請求引數和編碼

2019獨角獸企業重金招聘Python工程師標準>>> hot3.png

請求方法

框架提供了9種方法

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"
    Alamofire.request("https://httpbin.org/post", method: .post)

如果不指定預設使用GET方法

引數編碼

Alamofire提供了三種類型的引數編碼:URL, JSON 和 PropertyList.也可以遵守ParameterEncoding協議來自定義.

<!--more-->

URL編碼

  • .methodDependent//預設方法 根據請求方法判斷(GET直接拼接到URL中,HEAD and DELETE放到HTTP body中)
  • .queryString//直接拼接到URL中
  • .httpBody//放到HTTP body中
GET請求

//  以下三個寫法等價
Alamofire.request("https://httpbin.org/get", parameters: parameters) // encoding defaults to `URLEncoding.default`
Alamofire.request("https://httpbin.org/get", parameters: parameters, encoding: URLEncoding.default)
Alamofire.request("https://httpbin.org/get", parameters: parameters, encoding: URLEncoding(destination: .methodDependent))

// https://httpbin.org/get?foo=bar
POST請求
    "foo": "bar",
    "baz": ["a", 1],
    "qux": [
        "x": 1,
        "y": 2,
        "z": 3
    ]
]

// 以下三個寫法等價
Alamofire.request("https://httpbin.org/post", method: .post, parameters: parameters)
Alamofire.request("https://httpbin.org/post", method: .post, parameters: parameters, encoding: URLEncoding.default)
Alamofire.request("https://httpbin.org/post", method: .post, parameters: parameters, encoding: URLEncoding.httpBody)

// HTTP body: foo=bar&baz[]=a&baz[]=1&qux[x]=1&qux[y]=2&qux[z]=3

JSON編碼

以前我們需要把NSDictionary轉為NSData然後用NSJSONSerialization轉成JSON string JSON編碼給簡化了我們操作,它會建立一個JSON作為引數放在HTTP body中,對應的Content-Type 為application/json

例子

let parameters: Parameters = [
    "foo": [1,2,3],
    "bar": [
        "baz": "qux"
    ]
]
// Both calls are equivalent
Alamofire.request("https://httpbin.org/post", method: .post, parameters: parameters, encoding: JSONEncoding.default)
Alamofire.request("https://httpbin.org/post", method: .post, parameters: parameters, encoding: JSONEncoding(options: []))

// HTTP body: {"foo": [1, 2, 3], "bar": {"baz": "qux"}}

Property List 編碼

Property List編碼會建立一個plist作為引數放在HTTP body中,對應的Content-Type 為application/x-plist

自定義 Encoding

如果框架提供的引數編碼方式不能滿足需求,可以自定義編碼方式,下面是一個自定義JSONStringArrayEncoding轉JSON string array 的例子

struct JSONStringArrayEncoding: ParameterEncoding {
	private let array: [String]

    init(array: [String]) {
        self.array = array
    }

    func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
        var urlRequest = try urlRequest.asURLRequest()

        let data = try JSONSerialization.data(withJSONObject: array, options: [])

        if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil {
            urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
        }

        urlRequest.httpBody = data

        return urlRequest
    }
}

也可手動對請求進行編碼

let url = URL(string: "https://httpbin.org/get")!
var urlRequest = URLRequest(url: url)

let parameters: Parameters = ["foo": "bar"]
let encodedURLRequest = try URLEncoding.queryString.encode(urlRequest, with: parameters)

HTTP Headers

設定會直接改吧全域性請求,可以滿足請求頭不斷改吧的需求

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

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

在SessionManager中提供了所有請求的預設的請求頭設定,Session Manager Configurations章節中細說 下面列舉一些預設的引數

Accept-Encoding:gzip;q=1.0, compress;q=0.5
Accept-Language:en;q=1.0
User-Agent:iOS Example/1.0 (com.alamofire.iOS-Example; build:1; iOS 10.0.0) Alamofire/4.0.0

Authentication驗證

Authentication驗證基於系統 URLCredential and URLAuthenticationChallenge框架,授權驗證通常需要與後臺伺服器溝通來形成. 支援一下驗證方案

  • HTTP Basic
  • HTTP Digest
  • Kerberos
  • NTLM 例子
let user = "user"
let password = "password"

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

var headers: HTTPHeaders = [:]

if let authorizationHeader = Request.authorizationHeader(user: user, password: password) {
    headers[authorizationHeader.key] = authorizationHeader.value
}

Alamofire.request("https://httpbin.org/basic-auth/user/password", headers: headers)
    .responseJSON { response in
        debugPrint(response)
    }
    
let user = "user"
let password = "password"

let credential = URLCredential(user: user, password: password, persistence: .forSession)

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

系列目錄

轉載於:https://my.oschina.net/roycehe/blog/1057850