POST request not working in swift3 with alamofire - swift

I am using Alamofire for calling my API .
below is is the code.
func alamofirePost() {
let headers: HTTPHeaders = [ "content-type": "x-www-form-urlencoded"]
let todosEndpoint: String = "http://54.244.108.186:4000/api/post_upc"
let newTodo: [String: Any] = ["UPC": codeTextView.text, "DATE_TIME": currentTime() ]
print("i am in alamo")
Alamofire.request(todosEndpoint, method: .post, parameters: newTodo ,encoding: JSONEncoding.default,headers: headers )
.responseJSON { response in
guard response.result.error == nil else {
// got an error in getting the data, need to handle it
print("error calling POST on /todos/1")
print(response)
print(response.result.error!)
return
}
when i call the function , it is trying to inserting null values in the database
INSERT INTO `UPC`(`UPC`,`DATE_TIME`) VALUES (NULL,NULL)
Below is the response when i do in postman app.
can someone please help

Firstly in your Postman request you are POSTing your body as x-www-form-urlencoded but in your Swift example you are specifying that header as well. BUT you're actually submitting your POST body as a JSON payload. In contrast, your Postman request is a set of key/value pairs.
Additionally, the two keys appear to be named differently from your Swift example and your Postman example.
Swift uses UPC and DATE_TIME while Postman has upc_app and dttm_app so at a minimum you'll want to ensure you send along what your API expects

Related

Can't make post request using params as dictionary with Swift 4 & Alamofire

I'm trying to learn to call API with/without library. But the problem here confuses me.
I have params like this:
let parameters: [String:String] =
["key":"MY_KEY" ,
"q":sourceText,
"source": sourceLanguage),
"target": target)]
let headers: HTTPHeaders = [ "Content-type": "application/json"]
I make a post call like this:
Alamofire.request(urlString, method: HTTPMethod.post, parameters: parameters, headers: headers)
.responseJSON{ response in
guard response.result.error == nil else {
print("error calling POST on /todos/1")
print(response.result.error!)
return
}
// make sure we got some JSON since that's what we expect
guard let json = response.result.value as? [String: Any] else {
print("didn't get todo object as JSON from API")
print("Error: \(response.result.error)")
return
}
By this I get an error 403, saying that I do not have a valid API key (I tested the key with postman, and it is okay).
After many efforts, I have to change the code like this
let stringparams = "key=MY_KEY&q=\(sourceText)&source=\(sourceLanguage)&target=\(target)"
request.httpBody = stringparams.data(using: String.Encoding.utf8)
and using this: Alamofire.request(request)
it works!
I'm using Google Cloud Translation api. And the web use a REST api as said here: https://cloud.google.com/translate/docs/reference/translate
So why can't I use params as dictionary, but using the string (like formdata) will work here?
My guess is Alamofire didn't make the right BODY for the request from the parameters because other arguments is okay. But I don't know why.
And I think Google should accept a json params as they mentioned, in stead of using form data? I did try the original method, but it didn't work with JSON.
From what actually works for you it looks like you need to encode the parameters in the same style as a query. Try this:
struct ParameterQueryEncoding: ParameterEncoding {
func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
var request = try urlRequest.asURLRequest()
request.httpBody = parameters?
.map { "\($0)=\($1)" }
.joined(separator: "&")
.data(using: .utf8)
return request
}
}
You should then be able to perform the original call that you had before:
Alamofire.request(urlString,
method: HTTPMethod.post,
parameters: parameters,
encoding: ParameterQueryEncoding(),
headers: headers)
.responseJSON { response in
...
}
Try by using JSON encoding. Make sure you have removed ) from dictionary.
Alamofire.request(URL, method: method, parameters: parameters, encoding: JSONEncoding.default, headers: headers)

Is there a simple way to send a key, value in Alamofire in the body NOT param?

I need to send a list of strings under a key in the body. Alamofire makes parameters super simple but I can't figure out how to do it in the body of the request. This doesn't help me since its for a simple string and I can't figure out how to make it work for an array of strings: POST request with a simple string in body with Alamofire . This one is titled about a JSON body but the answer is giving them as params Alamofire 4, Swift 3 and building a json body . Does anyone have an answer or a link to something that actually solves my problem?
Code as requested:
var params = ["phone_numbers": [6314560046, 8458200476]] as [String: Any]
Alamofire.request(url, method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers).responseJSON() { response in
With Alamofire, the parameters are the body of the request. This creates your key with value of array of strings:
let parameters = ["Key": ["String1", "String2", "String3"]]
Then use the parameters in making the request:
Alamofire.request(URL, method: .post, parameters: paramaters, encoding: JSONEncoding.default)
.responseJSON { response in
print(response)
}

Display data from alamofire 3 + swiftyjson

I'm new in Swift and iOS-dev. I'm trying to create simple app working with JSON API.
I can get and print JSON data in console:
Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"])
.responseData { response in
print(response.request)
print(response.response)
print(response.result)
self.output = response.response // don't work, return nil
}
How can I display response with UITextView or UITableView? I just don't understand how to access data in closure..
Update
Looks like I miss something fundamental..:
Why it's return nil?

Alamofire POST Returning Data

I am using Alamofire to make a post request to server. The post request is working fine.
Issue: When the post request is made, it returns some data which I need. How can I store/ retrieve that data
The POST Request:
Alamofire.request(.POST, postURL, parameters: params)
to get the response closure add
.response { request, response, data, error in }
to the end of your code
ie
Alamofire.request(.POST, "http://httpbin.org/get", parameters: ["foo": "bar"])
.response { request, response, data, error in
print(request)
print(response)
print(data)
print(error)
}
If you are using the latest version of AlamoFire.
If you are using the latest version of AlamoFire.
Try this working fine for me.(Change request arguments based on your need)
let url1 = "http://yoururl.com"
let head = [ "Accept": "application/json;charset=UTF-8",
"Content-Type": "application/json;charset=UTF-8"] // Adding headers
let p = ["Email":"anything","Password": "123"] // Adding parameters if any
Alamofire.request(.POST,url1, parameters: p, encoding : .JSON, headers : head)
.responseJSON { response in
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
}

How can I retrieve the status message of a request made with Alamofire?

The server that I am using returns error messages in the HTTP status message. For example, it will return "400 User already exists" rather than "400 Bad Request".
I would like to access the string "User already exists" in the response method called by Alamofire. However, I cannot find any way to access this string.
I found this question on StackOverflow already: Swift Alamofire: How to get the HTTP response status code
Unfortunately, no one gives an answer to the question. :(
Here is where Chrome shows where the error is:
I would suggest trying to print out all the possible data fields that you are given and see what you can find. Please try the following example and see if that sheds any light.
let URL = NSURL(string: "your/url/to/somewhere")!
let parameters = ["foo": "bar"]
Alamofire.request(.POST, URL, parameters: parameters)
.response { request, response, data, error in
println("Request: \(request)")
println("Response: \(response)")
println("Error: \(error)")
if let data = data as? NSData {
println("Data: \(NSString(data: data, encoding: NSUTF8StringEncoding)!)")
}
}
Return response in json format from the server and then i think you'll be able to get the appropriate status.
I've implemented that thing using php codeigniter..from where my response is like
$response['status'] = 'user_already_exists';
$this->response($response, 400);
Now in swift you can go with this
Alamofire.request(.POST,URL, parameters:parameters) .responseJSON
{
(request, response, data, error) in
var json = JSON(data!) //I've used swiftyJSON for reading json response
let status = json["status"].stringValue
println("Status : \(status)")
}
Hope this may help you.