How to Post Parameter with (+ Plus Sign) in Alamofire

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
info.plist file

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



Leave a reply



Submit