使用Alamofire编码请求参数

2020-03-13  本文已影响0人  醉看红尘这场梦

向大家介绍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
上一篇下一篇

猜你喜欢

热点阅读