向大家介紹Alamofire中的parameter encoding。為什么需要parameter encoding呢挪捕?來看個例子。
我們發(fā)送一個最簡單的帶參數(shù)的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編譯執(zhí)行:
在PhpStorm中争便,我們可以看到级零,在服務端收到的數(shù)據(jù)中,foo的值滞乙,是字符串"1"奏纪,而不是整數(shù)值1,如何讓服務端直接接收到一個整數(shù)值呢酷宵?使用Alamofire parameter encoding就可以幫我們完成這個功能亥贸。
打開Alamofire的官網(wǎng)躬窜,我們可以看到浇垦,Alamofire提供了5種不同的參數(shù)encoding方式,我們介紹前三種的常見用法荣挨。
Parameter encoding in URL
對于一個GET / HEAD / DELETE請求來說男韧,我們可以直接在URL后面帶上要發(fā)送到服務器端的參數(shù),例如我們之前已經(jīng)用過的這個最簡單的形式:
https://apidemo.boxue.io/alamofire?XDEBUG_SESSION_START=PHPSTORM
它直接給服務器傳遞了一個叫做XDEBUG_SESSION_START的變量默垄,值是一個字符串"PHPSTROM"此虑。除了這種最簡單的key = value的形式之外,我們還可能會向服務器發(fā)送一個數(shù)組口锭,例如:
https://apidemo.boxue.io/alamofire?XDEBUG_SESSION_START=PHPSTORM&foo[]=1&foo[]=2
或者朦前,發(fā)送一個字典:
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編譯執(zhí)行,就可以看到我們發(fā)送到服務端的結果了:
這種通過拼接字符串發(fā)送請求的方式恩伺,是非常不易于維護的赴背,因此Alamofire允許我們在request方法里添加一個參數(shù),傳遞我們要發(fā)送的數(shù)據(jù)晶渠。Alamofire會自動對參數(shù)進行編碼凰荚,然后發(fā)送到服務器。
Parameter encoding in URL
首先褒脯,我們可以按照自己要發(fā)送的數(shù)據(jù)內容便瑟,構建一個數(shù)據(jù)結構:
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,重新編譯執(zhí)行爽彤,我們可以在PhpStorm里养盗,看到同樣的結果。如果我們注意一下發(fā)送到服務器的requestUrl适篙,就可以看到Alamofire自動把我們的參數(shù)編碼之后往核,添加在了URL后面。
那么Alamofire中指定的.URL和.URLEncodedInURL有什么區(qū)別呢嚷节?
對于.URL的編碼方式聂儒,Alamofire會在GET / HEAD / DELETE請求時,把參數(shù)直接追加在request url后面硫痰。
而對于POST / PUT請求衩婚,Alamofire則會把參數(shù)放在HTTP BODY里,而此時的request url效斑,就會是這樣:
此時非春,如果我們想強制讓request url帶上參數(shù),就可以使用.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奇昙,就可以看到結果了:
向服務器發(fā)送一個JSON
從上面這些例子可以看到,無論是.URL還是.URLEncodeInURL敌完,在服務端接收到的储耐,都是字符串值。為了實現(xiàn)一開始我們提到過的滨溉,讓服務器直接接收到一個整數(shù)值什湘,我們可以對要發(fā)送的參數(shù)采用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 編譯執(zhí)行之后,我們就可以在Laravel服務端看到闽撤,foo直接被解碼成了一個整數(shù)數(shù)組涧卵,而bar,則根據(jù)值的類型腹尖,被轉換成了相應的字符串和整數(shù)柳恐。