向大家介绍Alamofire中的parameter encoding。为什么需要parameter encoding呢?来看个例子。
我们发送一个最简单的带参数的GET请求:
let requestUrl = "https://apidemo.boxue.io/alamofire?XDEBUG_SESSION_START=PHPSTORM"
let parameters = [ "foo": 1 ]
Alamofire.request(.GET, requestUrl, parameters: parameters)
.responseJSON(completionHandler: { response in
switch response.result {
case .Success(let json):
print("JSON: ================")
print("\(json)")
case .Failure(let error):
print("\(error)")
}
})
按Command + R编译执行:
image在PhpStorm中,我们可以看到,在服务端收到的数据中,foo的值,是字符串"1",而不是整数值1,如何让服务端直接接收到一个整数值呢?使用Alamofire parameter encoding就可以帮我们完成这个功能。
打开Alamofire的官网,我们可以看到,Alamofire提供了5种不同的参数encoding方式,我们介绍前三种的常见用法。
Parameter encoding in URL
对于一个GET / HEAD / DELETE请求来说,我们可以直接在URL后面带上要发送到服务器端的参数,例如我们之前已经用过的这个最简单的形式:
https://apidemo.boxue.io/alamofire?XDEBUG_SESSION_START=PHPSTORM
它直接给服务器传递了一个叫做XDEBUG_SESSION_START的变量,值是一个字符串"PHPSTROM"。除了这种最简单的key = value的形式之外,我们还可能会向服务器发送一个数组,例如:
https://apidemo.boxue.io/alamofire?XDEBUG_SESSION_START=PHPSTORM&foo[]=1&foo[]=2
或者,发送一个字典:
https://apidemo.boxue.io/alamofire?XDEBUG_SESSION_START=PHPSTORM&bar[x]=a&bar[y]=2
如果我们要同时使用它们,就会变成这样:
https://apidemo.boxue.io/alamofire?XDEBUG_SESSION_START=PHPSTORM&foo[]=1&foo[]=2&bar[x]=a&bar[y]=2
当我们使用这种URL的时候,我们要先使用下面的方法,对URL进行编码:
let requestParameters = "&foo[]=1&foo[]=2&bar[x]=a&bar[y]=2"
requestUrl = requestUrl + requestParameters
requestUrl.stringByAddingPercentEncodingWithAllowedCharacters(
NSCharacterSet.URLQueryAllowedCharacterSet()
)
let encodedUrl =
requestUrl.stringByAddingPercentEncodingWithAllowedCharacters(
NSCharacterSet.URLQueryAllowedCharacterSet()
)!
然后,按Command + R编译执行,就可以看到我们发送到服务端的结果了:
image这种通过拼接字符串发送请求的方式,是非常不易于维护的,因此Alamofire允许我们在request方法里添加一个参数,传递我们要发送的数据。Alamofire会自动对参数进行编码,然后发送到服务器。
Parameter encoding in URL
首先,我们可以按照自己要发送的数据内容,构建一个数据结构:
let parameters = [
"foo": [1, 2],
"bar": [
"x": "a",
"y": "2"
]
]
然后,我们可以这样使用Alamofire.request:
let requestUrl = "https://apidemo.boxue.io/alamofire?XDEBUG_SESSION_START=PHPSTORM"
let parameters = [
"foo": [1, 2],
"bar": [
"x": "a",
"y": "2"
]
]
Alamofire.request(.GET, requestUrl, parameters: parameters, encoding: .URL)
显然,这样的方式看上去要好的多。按Command + R,重新编译执行,我们可以在PhpStorm里,看到同样的结果。如果我们注意一下发送到服务器的requestUrl,就可以看到Alamofire自动把我们的参数编码之后,添加在了URL后面。
image那么Alamofire中指定的.URL和.URLEncodedInURL有什么区别呢?
对于.URL的编码方式,Alamofire会在GET / HEAD / DELETE请求时,把参数直接追加在request url后面。
而对于POST / PUT请求,Alamofire则会把参数放在HTTP BODY里,而此时的request url,就会是这样:
image此时,如果我们想强制让request url带上参数,就可以使用.URLEncodedInURL编码:
let requestUrl = "https://apidemo.boxue.io/alamofire?XDEBUG_SESSION_START=PHPSTORM"
let parameters = [
"foo": [1, 2],
"bar": [
"x": "a",
"y": "2"
]
]
Alamofire.request(.POST, requestUrl, parameters: parameters, encoding: .URLEncodedInURL)
此时,在服务端查看request url,就可以看到结果了:
image向服务器发送一个JSON
从上面这些例子可以看到,无论是.URL还是.URLEncodeInURL,在服务端接收到的,都是字符串值。为了实现一开始我们提到过的,让服务器直接接收到一个整数值,我们可以对要发送的参数采用JSON编码。
let requestUrl = "https://apidemo.boxue.io/alamofire?XDEBUG_SESSION_START=PHPSTORM"
let parameters = [
"foo": [1, 2],
"bar": [
"x": "a",
"y": 2
]
]
Alamofire.request(.POST, requestUrl, parameters: parameters, encoding: .JSON)
按 Command + R 编译执行之后,我们就可以在Laravel服务端看到,foo直接被解码成了一个整数数组,而bar,则根据值的类型,被转换成了相应的字符串和整数。
image
网友评论