httpBody [Any] to alamofire - swift

i need to set body of the request to something like that
let param = [[["user_id", "=", 31]]]
the problem is that body of alamofire is like that [string : Any]
how can i send object [Any]to httpBody
i can't send json because only what accepted by the request is form-data like image show
When i add json raw like that
{"domain" : ["user_id","=",31]}
i'm getting error
{
"jsonrpc": "2.0",
"id": null,
"error": {
"code": 200,
"message": "Odoo Server Error",
"data": {
"name": "werkzeug.exceptions.BadRequest",
"debug": "Traceback (most recent call last):\n File \"/data/som.dev.arkeup.com/server/odoo/http.py\", line 646, in _handle_exception\n return super(JsonRequest, self)._handle_exception(exception)\n File \"/data/som.dev.arkeup.com/server/odoo/http.py\", line 307, in _handle_exception\n raise pycompat.reraise(type(exception), exception, sys.exc_info()[2])\n File \"/data/som.dev.arkeup.com/server/odoo/tools/pycompat.py\", line 87, in reraise\n raise value\n File \"/data/som.dev.arkeup.com/server/odoo/http.py\", line 683, in dispatch\n result = self._call_function(**self.params)\n File \"/data/som.dev.arkeup.com/server/odoo/http.py\", line 315, in _call_function\n raise werkzeug.exceptions.BadRequest(msg % params)\nwerkzeug.exceptions.BadRequest: 400: Bad Request\n",
"message": "",
"arguments": [],
"exception_type": "internal_error"
}
}
}
__________________EDIT
I think if i put this string it's will work [[["user_id", "=", 31]]]
but how can i pass [Any]? to body ?
_____EDIT
Here my ios code
let methodName = HTTPMethod.get
let headers = [ "Content-Type" : "application/x-www-form-urlencoded" ,"Accept-Encoding" : "application/json", "accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8"]
let data = ["domain":[[["user_id", "=", 31]]]]
manager.request(urlS!, method: methodName, parameters: data, encoding: URLEncoding.default, headers: headers)//.responseJSON{response in
.responseString(encoding: String.Encoding.utf8) { (response) -> Void in
switch (response.result)
{
case .success:
}
Thank's you for your responses

Related

Swift - Request to REST Api - Not readable

I'm sending a request to an API, but it always responds with an error Not readable http body.
In message it returns:
exception = "class org.springframework.http.converter.HttpMessageNotReadableException";
httpCode = 400;
httpMessage = "Bad Request";
Could not read document: Unrecognized token 'product': was expecting ('true', 'false' or 'null')\n at [Source: java.io.PushbackInputStream#430128e1; line: 1, column: 9]; nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'product': was expecting ('true', 'false' or 'null')\n at [Source: java.io.PushbackInputStream#430128e1; line: 1, column: 9]
But product isn't boolean, but string.
Anyone know, what's wrong?
let api_key = Data(klic.utf8).base64EncodedString()
let parametry = ["product" : "STANDART"] as [String : Any]
let headers = ["authorization" : "Basic \(api_key)", "content-type" : "application/json", "cache-control" : "no-cache"]
Alamofire.request("https://stage.japostparcel.cz/api/v1/order/", method: .post, parameters: parametry, headers: headers).responseJSON { (response) in
//print(NSString(data: (response.request?.url)!, encoding: String.Encoding.utf8.rawValue))
print(response)
}
Your base url ends with order/ so you post something like order/?product= STANDART. I am pretty sure you need some kind of page ref in between and not /? something like
`order/order_page?product= STANDART`
So check the documentation

Alamofire Form Encoded POST Request Failing with responseSerializationFailed

Making a request with Alamofire (swift 4) to an api endpoint (form encoded content type) and passing a username and password via login. When testing in POSTMAN, this endpoint works without errors and returns valid JSON (see below).
My swift code is as follows:
let headers = [
"content-type": "application/x-www-form-urlencoded",
"cache-control": "no-cache"
]
let parameters = [
"username": "user#user.com",
"password": "password"
]
Alamofire.request("https://xxxxx.com/api/login/", method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseJSON { response in
print(response)
}
The response I get is as follows:
FAILURE: responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.}))
Any insight would be appreciated!
Change JSONEncoding.default to URLEncoding.default as below,
Alamofire.request("https://xxxxx.com/api/login/", method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON { response in
print(response)
}

PayPal SDK request for access token returns code 401 (unauthorized)

I am trying to receive an access token from PayPal's server using the authorization code in a Sandbox environment. I believe the problem is in converting curl to an Alamofire request, but I'm not sure. Any help is appreciated.
Here is my code for sending authorization to server:
func sendAuthorizationToServer(authorization: [AnyHashable: Any]) {
let jsonAuth = JSON(authorization)
let headers = [
"content-type": "application/x-www-form-urlencoded; charset=utf-8",
]
let parameters = [
"client_id": Constants.payPalSandboxID,
"client_secret": Constants.payPalSandboxSecret,
"grant_type": "authorization_code",
"redirect_uri": "urn:ietf:wg:oauth:2.0:oob",
"code": jsonAuth["response"]["code"].stringValue
]
Alamofire.request("https://api.sandbox.paypal.com/v1/oauth2/token", method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON { response in
print(response.request)
print(response.response)
print(response.data)
print(response.error)
}
}
I've checked jsonAuth["response"]["code"].stringValue and it is returning a correct authorization code.
My doubts are if it should be a .post request or a .get request, and if my credentials in the parameters are in the correct order/structure.
Here is the output of the last print statements:
Here is the SDK link for exchanging an authorization code for the access token:
https://github.com/paypal/PayPal-iOS-SDK/blob/master/docs/future_payments_server.md#exchange-authorization-code-for-refresh--access-tokens
import SwiftyJSON
import Alamofire
// ... ...
// ... ...
// ... ...
let credentialData = "\(paypalClientId):\(paypalSecret)".data(using: String.Encoding.utf8)!
let base64Credentials = credentialData.base64EncodedString(options: [])
let headers = [
"Authorization": "Basic \(base64Credentials)",
]
let params:[String: Any] = [
"grant_type": "client_credentials",
]
Alamofire.request(tokenAPI, method: .post, parameters: params, encoding: URLEncoding.default, headers: headers)
.validate()
.responseJSON { (response) in
debugPrint(response)
switch response.result {
case .success(let data):
let json = JSON(data)
let accessToken = json["access_token"].stringValue
break;
case .failure(let error):
debugPrint(error)
debugPrint(response.data)
}
}
Please note that encoding must be URLEncoding.default not the JSONEncoding.default

Calling an API with HTTP Header and Body with Alamofire

I'm trying to recreate a POST request that already works in Postman in Swift 3 with Alamofire 4, but i'm always getting a Status Code 400 "Bad Request". I am out of ideas about what I'm doing wrong here.
This is the request in Postman, additionally there is a username and password in the Body in JSON format:
Reading the Docs for Alamofire, I thought this should be the correct Swift code:
func login(as username: String, withPassword password: String) {
let url = "https://api2.drive-now.com/login"
let parameters: Parameters = [
"username" : username,
"password" : password
]
let loginHeaders: HTTPHeaders = [
"Accept" : "application/json;v=1.6",
"Accept-Encoding" : "gzip, deflate, sdch",
"Accept-Language" : "de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4",
"Connection" : "keep-alive",
"Host" : "api2.drive-now.com",
"Origin" : "https://de.drive-now.com",
"X-Api-Key" : "adf51226795afbc4e7575ccc124face7",
"X-Language" : "de",
"Content-Type" : "application/json"
]
Alamofire.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: loginHeaders).responseJSON { response in
print("Request: \(response.request)") // original URL request
print("Response: \(response.response)") // HTTP URL response
print("Data: \(response.data)") // server data
print("Result: \(response.result)") // result of response serialization
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
}
My console output is:
Request: Optional(https://api2.drive-now.com/login)
Response: Optional(<NSHTTPURLResponse: 0x6000000266a0> { URL: https://api2.drive-now.com/login } { status code: 400, headers {
Connection = close;
"Content-Length" = 181;
"Content-Type" = "text/html";
Date = "Tue, 13 Dec 2016 22:12:46 GMT";
Server = "nginx/1.4.6 (Ubuntu)";
} })
Data: Optional(181 bytes)
Result: FAILURE
Is there a custom session manager maybe that I have to implement? Or do you know of any debugging methods I could use here?
A friend accustomed to the API did help me resolve the issue: it was a default header field that seems to be added by Alamofire to every call. The API didn't accept calls with a "User-Agent" set (don't ask me why).
To help others who might have the same problem, I share the steps I went through to find and resolve the issue:
I made Alamofire.request(...) into a variable named postage (you can call it however you like, of course)
I added debugPrint(postage) to the end of the login-function
The output showed the additional header field
I constructed a custom SessionManager like below
var headers = Alamofire.SessionManager.defaultHTTPHeaders
headers.removeValue(forKey: "User-Agent")
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = headers
api = Alamofire.SessionManager(configuration: configuration)

CURL command in Alamofire with swift

I have the following working curl command which I need to run in Swift using Alamofire.
curl -k -i -d '{ "user": {"displayName":"My Test" ,"email":"test#xxtest.com","pwd":"test","roles":["stu"]}}' -H "Content-Type: application/json;charset=UTF-8" -u web:web -X POST 'https://test.herokuapp.com/xtest/auth/register'
I tried out the following method with Swift by using Alamofire. I have the impression that I do -u web:web wrong, but I have no means to confirm that.
The console gives me the following error which I don't understand:
print response object
nil
print error
Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.})
Can someone point out what is wrong in here? Thx.
This is the function which translates the CURL command into Swift
func registerNewStudent(displayName: String, email: String, password: String, completionHandler: (AnyObject?, NSError?) -> ()) {
//Basic HTTP auth
let user = "web"
let password = "web"
let credentialData = "\(user):\(password)".dataUsingEncoding(NSUTF8StringEncoding)!
let base64Credentials = credentialData.base64EncodedStringWithOptions([])
let headers = ["Authorization": "Basic \(base64Credentials)"]
//example for a nested array query
let parameters = [
"user": [
"displayName": displayName,
"email": email,
"pwd": password,
"roles":["stu"]
]
]
Alamofire.request(
.POST,
registerURL,
headers: headers,
parameters: parameters
)
.responseJSON { response in
switch response.result {
case .Success(let value):
completionHandler(value, nil)
case .Failure(let error):
completionHandler(nil, error)
}
}
}
I call this function in the following way:
func okButtonTapped(sender: UIButton) {
let displayNameText = displayNameInput.text
let emailText = emailInput.text
let passwordText = passwordInput.text
restApi.registerNewStudent(displayNameText!,emailInput: emailText!, passwordInput: passwordText!) {responseObject, error in
// use responseObject and error here
print("print response object")
print(responseObject)
print("print error")
print(error)
}
Response from the CURL call:
{"result":{"email":"trrrrrest#xxtest.com","display_name":"My Test","pwd":"test","fb_id":null,"roles":["stu"]
I could resolve it from here: http://www.ceus-now.com/curl-d-to-alamofire/
Adding the following line after the JSON response did the trick (not before).
.authenticate(user: "web", password: "web")
so the method looks like:
Alamofire.request(
.POST,
registerURL,
parameters: parameters
)
.responseJSON { response in
switch response.result {
case .Success(let value):
completionHandler(value, nil)
case .Failure(let error):
completionHandler(nil, error)
}
}
.authenticate(user: "web", password: "web")
}