Swift Alamofire "+" sign removed from DB when request was sent - ios

We're having this weird issue. The "+" is removed at the DB once we sent our request.
But if I print the response.data, I can see that the "+" is there (using Alamofire 4.9.1)
What could be the possible reason why the "+" is removed?
Here's how I set the request and the headers:

For the sake of future readers, application/x-www-form-urlencoded requests must be “percent encoded”, replacing the + character with %2B. But there are actually lots of characters that might need encoding, so it is generally best to use the Alamofire request method with Parameters, which takes care of all of those details for you. E.g. in Alamofire 4.9.1:
let headers: HTTPHeaders = [
"Authorization": authorization
]
let parameters: Parameters = [
"grant_type": "password",
"username": username,
"password": password
]
Alamofire.request(url, method: .post, parameters: parameters, headers: headers).responseJSON { response in
switch response.result {
case .failure(let error): print(error)
case .success(let value): print(value)
}
}
Or in Alamofire 5 and later, one would use AF rather than Alamofire:
AF.request(url, method: .post, parameters: parameters, headers: headers).responseJSON { response in
switch response.result {
case .failure(let error): print(error)
case .success(let value): print(value)
}
}
See the Alamofire usage document: POST Request With URL-Encoded Parameters
If you really want to build the httpBody of the URLRequest yourself, rather than just percent-encoding only the + character, you might consider a more generalized percent-coding routine, as shown in JSON request sending empty data. The idea is the same as what Alamofire’s Parameters, namely build the httpBody from a dictionary.

Turns out, the "+" is not being escaped properly. So I had to replace "+" with "%2B"
let requestString = "grant_type=password&username=" + encryptedTokenUsernameBody + "&password=" + encryptedTokenPasswordBody
let encodedString = requestString.replacingOccurrences(of: "+", with: "%2B")

Related

Getting bad request error in FedEx OAuth Swift

I am trying to authorised FedEx token but getting 400 error.
FedEx Developer link : https://developer.fedex.com/api/en-us/catalog/authorization/v1/docs.html#operation/API%20Authorization
Code Snippet :
let headers = [
"Content-Type": "application/x-www-form-urlencoded"
]
let parameters = [
"grant_type":"client_credentials",
"client_id":"***********************",
"client_secret":"***********************"
] as [String : Any]
Alamofire.request("https://apis-sandbox.fedex.com/oauth/token", method: .post, parameters:parameters,encoding: JSONEncoding.default, headers: headers).responseJSON {
response in
switch response.result {
case .success:
print(response)
break
case .failure(let error):
print(error)
}
}
Getting Error :
{
errors = (
{
code = "BAD.REQUEST.ERROR";
message = "Missing or duplicate parameters. Please modify your request and try again.";
}
);
transactionId = "b1d9d540-ed29-49fd-a4c2-907718e918c2";
}
From the FedEx documentation you can see that the parameters need to be sent as form-urlencoded.
And indeed, you have specified this in your headers, but then you have used a JSON encoder, so a JSON document will be sent.
Rather, use
Alamofire.request("https://apis-sandbox.fedex.com/oauth/token",method: .post, parameters: parameters, encoder: URLEncoding.default, headers: headers)

Alamofire 4 missing parameters in POST

Spent hours on this with no success.
I'm using Alamofire to make a HTTP POST to back end server which requires some parameters to be supplied with request.
I'm successfully hitting the server but the server is responding with a 500 stating no parameters were sent?
I've tried most of the SO solutions (changing the encoding type, setting parameters as NSDict, etc) but with no success.
Any help greatly appreciated.
PS its Swift3 with Alamofire 4
Code:
let params: [String: String] = ["deviceID": "Some device ID",
"email": "email","password": "password","userid": "1234",
"username":"gordon"]
let request_params: Parameters = ["LoginUser" : params]
let url = "https://myserver/LogIn" as String
Alamofire.request(url, method: .post, parameters: request_params, encoding: URLEncoding.default, headers: [
"Content-Type": "application/x-www-form-urlencoded"
]).responseString { (response:DataResponse<String>) in
switch(response.result) {
case.success(let data):
print("success",data)
print(response.response)
case.failure(let error):
print("Failed!",error)
}
}
Update:
Below is the body of the POST, it looks like this is where the problem exists:
Alamofire POST body (from above code) -
(LoginUser%5BdeviceID%5D=12345&LoginUser%5Bemail%5D=gordon%40test.com&LoginUser%5Buserid%5D=00000000-0000-0000-0000-000000000000&LoginUser%5Bpassword%5D=testPassword&LoginUser%5Busername%5D=gordon)
It should be something like (ignoring the encoding values):
This is a functional post body-
LoginUser=%7B%22deviceID%22%3A%22%22%2C%22email%22%3A%22gordon%40test.com%22%2C%22password%22%3A%22testPassword%22%2C%22userid%22%3A%2200000000-0000-0000-0000-000000000000%22%2C%22username%22%3A%22gordon%22%7D
As you can see the Alamofire post seems to concatenate the LoginUser to start of each attribute? Also missing the LoginUser= at start??
Try to use JSONEncoding.default instead of URLEncoding.default
OK so I got this working with the below code, would be very interested in understanding if this is the most efficient means of posting param?
let params: NSMutableDictionary? = ["deviceID": "someDeviceID",
"email": "emailAddress","password": "aSecret","userid": "12345",
"username":"gordon"]
let url = "https://serverAdrress" as String
let data = try! JSONSerialization.data(withJSONObject: params!, options: JSONSerialization.WritingOptions.prettyPrinted)
let json: NSString! = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
let request_params: Parameters = ["LoginUser" : json as Any]
Alamofire.request(url, method: .post, parameters: request_params, encoding: URLEncoding.httpBody, headers: [
"Content-Type": "application/x-www-form-urlencoded"
]).responseString { (response:DataResponse<String>) in
switch(response.result) {
case.success(let data):
print("success",data)
print(NSString(data: (response.request?.httpBody)!, encoding: String.Encoding.utf8.rawValue))
print(response.response)
case.failure(let error):
print("Not Success",error)
}
}

Alamofire server requests converts integer parameters to string

I have to send request having fields such as
id:1
Issue is that when I check apache logs I see that field is in form of
id:"1"
That is rather than having Integer 1 , I am getting String "1". Here is my code
let parameters: Parameters = [
"viewModel":viewModel];
let headers: HTTPHeaders = [
"Authorization": "Bearer " + getToken(),
"Accept": "application/json"
]
Alamofire.request(setUrl(),method:.post,parameters:parameters,headers: headers).responseJSON{
response in
print("Response:\(String(describing:response.result.value))")
switch response.result {
case .success:
self.status = true;
if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
self.responseString = utf8Text
}
self.responseJSON = JSON(response.result.value as Any)
case .failure:
self.status = false;
}
completed()
}
Before request is initiated , i have made sure that all required fields are in Integer. Other fields are string , hence I am using Dictionary of Type [String:Any]
What am I doing wrong? I need to make sure that integer fields remain integer.
Setting encoding to
JSONEncoding.default
worked perfectly for me.
The request can also be like
Alamofire.request(url, method: .post, parameters: object, encoding: JSONEncoding.default)
And works great with other types of methods too!
I Know this is a late reply, Surely it will help someone. I have also faced the same issue, and took couple of hours to figure it out.
You need to set encoding in Alamofire request inorder to solve this issue.
encoding: JSONEncoding.default
So the request will be like
Alamofire.request(setUrl(),method:.post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseJSON{
response in

Setting content-type header to use JSON with Swift 3 + AlamoFire

The answers in Alamofire Swift 3.0 Extra parameter in call did not work for me.
Setting header to nil compiles but I need ["Content-Type", "application/json"]. Here I get an error of an extra parameter in th emethod
How do I take
manager.request(url, method: .get, parameters: parameters).responseJSON {
response in
fulfill(response)
}
}
and send JSON content-type?
The documentation shows
Automatic Validation
Automatically validates status code within 200..<300 range, and that the Content-Type header of the response matches the Accept header of the request, if one is provided.
Alamofire.request("https://httpbin.org/get").validate().responseJSON { response in
switch response.result {
case .success:
print("Validation Successful")
case .failure(let error):
print(error)
}
}
I'm using .responseJSON but I'm not getting JSON back. So I think I need to send the Content-Type header.
Try this, there is another method overload that allow pass a dictionary with headers
let request = Alamofire.request(requestUrl, method: .get, parameters: [:], encoding: URLEncoding.queryString, headers: ["Content-Type" :"application/json"]).responseData { (response) in
/***YOUR CODE***/
}
for post JSON data in request check this answer Using manager.request with POST
Hope this helps you

Alamofire extra argument 'method' in call from Alamofire example

I would like to state that I've tried every single example and scanned the plethora of other questions exactly like mine to no avail, so I have NO CHOICE but to post.
Xcode: 8.3.1 (8E1000a)
Apple Swift version 3.1 (swiftlang-802.0.51 clang-802.0.41)
Target: x86_64-apple-macosx10.9
OSX 10.12.4
Please see the code:
Note: This is embedded in a function, the parameters "email" and "password" are strings and are available, I also tried setting static string values.
let url = URL(string: "http://website.what.com/api/v1/login")
let params: Parameters = ["email": email, "password":password]
// This Works
Alamofire.request(url!, method: .post, parameters: params)
.responseJSON { response in
switch response.result {
case .success:
print(response)
case .failure(let error):
print(error)
}
}
// This one returns: "Extra argument Method in call"
let parameters: Parameters = [
"foo": [1,2,3],
"bar": [
"baz": "qux"
]
]
Alamofire.request("https://httpbin.org/post", method: .post, parameters: parameters, encoding: JSONEncoding.default)
.responseJSON { response in
switch response.result {
case .success:
print(response)
case .failure(let error):
print(error)
}
}
The primary I am confident in posting again - the second example was taken straight from the Alamofire github README.
If I am missing something - as in incorrectly encoding a parameter (which I copied directly from Alamofire's github page) or something.
Alternately, if someone can provide me a working sample on Swift 3.1 which allows me to use JSON, Headers, and POST Method.
The first "working" method does not have headers, I am not sure if I can use that example with additional parameters or not?
Sorry for the trouble, very very fresh swift learner who is diving head-first into a complicated world.

Resources