How to post parameter with (+ plus sign) in Alamofire
Unfortunately, URLComponents
will not percent encode +
character although many (most?) web services require it to be (because, pursuant to the x-www-form-urlencoded
spec, they replace +
with space character). When I posted bug report on this, Apple's response was that this was by design, and that one should manually percent encode the +
character:
var components = URLComponents(string: "https://www.wolframalpha.com/input/")!
components.queryItems = [
URLQueryItem(name: "i", value: "1+2")
]
components.percentEncodedQuery = components.percentEncodedQuery?.replacingOccurrences(of: "+", with: "%2B")
Obviously, if you were doing a standard application/json
request, with the JSON in the body of the request, no such percent encoding is needed. But if you're going to include the JSON in the URL like this, then you will have to percent encode the +
character yourself.
Alternatively, you can let Alamofire do this for you:
let parameters = [
"api_key": apiKey,
"profile": jsonString
]
Alamofire.request(url, method: .post, parameters: parameters).responseJSON { response in
...
}
This, admittedly puts the properly percent encoded value in the body of the POST
request, not the URL as in your example, but generally in POST
requests, that's what we want.
Alamofire - add both query parameter and body
Alamofire's URLEncoding
has an initializer that gets destination
as parameter. Based on documentation:
Destination
defining where the encoded query string will be applied..methodDependent
by default.
By default .methodDependent
case checks the HTTP method of the request and only on .get
, .head
and .delete
requests it encodes the passed parameters in the URL.
Given that fact, you never see paramA
in your request (not even in the body) because you override it in the following line:
// here body is already serialized to Json
request.httpBody = Data(bodyInJsonString.utf8)
So, instead of using the default URLEncoding
, you can simply call URLEncoding
's initializer directly passing as destination
the .queryString
case like this:
// here I am specifying `paramA` value
request = try URLEncoding(destination: .queryString).encode(request, with: parameters)
// here body is already serialized to Json
request.httpBody = Data(bodyInJsonString.utf8)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
That way you will have a request with paramA
in the URL and your JSON as a body.
How to POST a request with user data with Alamofire 5 in Swift 5
I think issue is encoding type.Add preferred encoding type.
if you are are getting parameters through form data
encoding: URLEncoding.default
gettting parameters through row data as json
encoding: JSONEncoding.default
request like this,
AF.request(URL_USER_REGISTER
,method: .get,
parameters: parameters,
encoding: URLEncoding.default
).response {response in
print(response)
}
}
make sure your project allow http requests in info.plist and use http://192.... instead of localhost in AF request
How to multiple encoding parameters for put method Alamofire Request
If you want those in your URL, you're going to have to percent-encode them. You can do this using URLComponents
.
So, build your JSON string however you want:
let dictionary = [
"birthday": "1994-01-01",
"gender": "MALE",
"marital": "SINGLE"
]
let data = try! JSONEncoder().encode(dictionary)
let jsonString = String(data: data, encoding: .utf8)!
Then you can build the URL and perform the request:
let urlString = "http://et.net/webservice/put/profile"
var components = URLComponents(string: urlString)!
components.queryItems = [
URLQueryItem(name: "api_key", value: "[K]"),
URLQueryItem(name: "m", value: "[M]"),
URLQueryItem(name: "profile", value: jsonString)
]
Alamofire.request(components.url!, method: .put)
.response { response in
// do whatever you want
}
If you were building a .post
request, you could let Alamofire encode this into the body of the request for you:
let parameters = [
"api_key": "[K]",
"m": "[M]",
"profile": jsonString
]
Alamofire.request(urlString, method: .post, parameters: parameters)
.response { response in
// do whatever you want
}
Alamofire post request:
There are many ways to implement the requests using Alamofire, this is a simple example:
First, do you have to create the parameters, URL from your API and headers:
let parameters = [
"username": "foo",
"password": "123456"
]
let url = "https://httpbin.org/post"
static private var headers: HTTPHeaders {
get {
return [
"Authorization" : "Bearer \(Session.current.bearerToken ?? "")"
]
}
}
So you call the function from Alamofire and pass your data:
Alamofire.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseJSON {
response in
switch (response.result) {
case .success:
print(response)
break
case .failure:
print(Error.self)
}
}
}
:)
How to perform a post with Alamofire (swift) to get a security token as return value
Let's make use of usefull debug tools of Alamofire since you have a cURL
sample.
Let's break your current code:
let headers = ["Content-Type": "application/x-www-form-urlencoded"]
let params = ["grant_type": "client_credentials"]
let request = Alamofire.request("https://test.api.amadeus.com/v1/security/oauth2/token",
method: .post,
parameters: params,
encoding: JSONEncoding.default,
headers: headers).authenticate(user: "API", password: "API")
print(request.debugDescription)
request.responseJSON { response in
debugPrint(response)
let result = response.result.value
print(result)
}
Output:
$>curl -v \
-X POST \
-u API:API \
-H "Accept-Language: fr-US;q=1.0, en;q=0.9, fr-FR;q=0.8" \
-H "Accept-Encoding: gzip;q=1.0, compress;q=0.5" \
-H "User-Agent: iOSTest/1.0 (nt.iOSTest; build:1; iOS 12.2.0) Alamofire/4.8.1" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "{\"grant_type\":\"client_credentials\"}" \
"https://test.api.amadeus.com/v1/security/oauth2/token"
Let's go piece by piece:
We should forget about Accept-Encoding, User-Agent & Accept-Language headers. I'll skip them later.
We see that the -d
(data into httpBody) is wrong.
Let's change that: encoding: JSONEncoding.default
to encoding: URLEncoding(destination: .httpBody)
. Plus it makes sense since in the content type we said it was url encoded.
We get then:
$>-d "grant_type=client_credentials"
Seems better.
We see the -u API:API \
which correspond to .authenticate(user: "API", password: "API")
. We might want to remove it if the server doesn't manage authentification like that and put it into the params instead.
So now, let's change the params:
let params = ["grant_type": "client_credentials",
"client_id" : "APIKey",
"client_secret" : "APISecret"]
We get:
$>-d "client_id=APIKey&client_secret=APISecret&grant_type=client_credentials" \
It should work then.
The order is not the same, but server shouldn't care about it. It should be a key/access not an index/access.
So final:
let headers = ["Content-Type": "application/x-www-form-urlencoded"]
let params = ["grant_type": "client_credentials",
"client_id" : "APIKey",
"client_secret" : "APISecret"]
let request = Alamofire.request("https://test.api.amadeus.com/v1/security/oauth2/token",
method: .post,
parameters: params,
encoding: URLEncoding(destination: .httpBody),
headers: headers)
print(request.debugDescription)
request.responseJSON { response in
debugPrint(response)
let result = response.result.value
print(result)
}
Output (with skipped headers):
$ curl -v \
-X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=APIKey&client_secret=APISecret&grant_type=client_credentials" \
"https://test.api.amadeus.com/v1/security/oauth2/token"
Related Topics
Arkit - Place a Scnplane Between 2 Vector Points on a Plane in Swift 3
Cloudkit - What to Do When a User Adds, Modifies or Deletes an Object While Offline
How to Drag a Working Slider Using Swiftui
It Is Posible to Load Customise HTML View into Webview in Swift
Swift: How to Continuously Send an Action from a Nstextfield
Swift Dictionary Initialization of Custom Type Gives: '>' Is Not a Postfix Unary Operator Error
Connecting Avaudiosourcenode to Avaudiosinknode Does Not Work
How to Update User Interface on Core Data
Swift Guard Else Called on Dictionary Key with Null Value
How to Convert a Pair of Bytes into a Float Using Swift
Cannot Assign Value of Type 'Menuview' to Type 'some View'
Sprite Kit Game Crashes on Game Over on Tvos 9.1 and iOS 9.2
How to Set Window Level in Swift
How to Use Mtlblitcommandencoder for Copying Interlaced Video Fields into a Mtlbuffer
Change The 2Nd and 3Rd Pickerview Acording to What Row from The 1St Picker Is Selected
Get Out of Navigation Controller and Go Back to Tab Bar View