Send Array of Request Body in an Alamofire Request - ios

I have to send an array of request body and following is the request body that i have to send
[{
"user": "abc",
"id": "demo"
}]
What i've tried?
var requestArray = [[String: String]]()
let params = [
"user": "abc",
"id": "demo"
]
requestArray.append(params)
var request = URLRequest(url: URL.init(string: myUrl)!)
request.httpMethod = ".post"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try! JSONSerialization.data(withJSONObject: requestArray)
Alamofire.request(request)
.response{
response in
print("Request Body:- \(response.request)")
print(response)
}
Problems that i am facing
URL works flawlessly in both Postman and an Android App
Above solution is not working for me. My web service returns me 400 error code (Bad Request)
I am new to iOS development so any help will be appreciated.

Guys i have fixed the issue. I was playing around with some of the solutions from you guys and suddenly it worked!
So what was the main problem?
I changed the request.httpMethod = ".post" to request.httpMethod = "post".
Initially this did not work when i commented back to #NiravD but after some time when i did the changes below, i was able to see the output
Additional changes to view the response on console
Replaced .response to .responseJSON
Thanks a lot to everyone who helped :)

First of all Alamofire requires Parameter to be of type [String: Any], and the second you don't need to make a post request like that. No need for JSONSerialization. Try this and it will be ok.
let params: [String: Any] = [
"user": "abc",
"id": "demo"
]
Alamofire.request(URL.init(string: myUrl)!, method: .post, parameters: params)
.validate()
.responseString {
(response) in
print(response)
}

May be you are missing headers. Can you try it adding the headers that you can see n postman?

Please try this
// this should accompaign your required work [[String:Any]]
var requestArray = [AnyObject] // => Array to conatin dictionaries of type [String: Any]
var dictionaryObject = [String: AnyObject] // => to create some dictionary to append in requestArray
dictionaryObject["user"] = "abc"
dictionaryObject["id"] = "demo"
requestArray.append(dictionaryObject)
Alamofire.request(URL.init(string: myUrl)!, method: .post, parameters: requestArray).validate().responseString { (response) in
print(response)
}

You must pass your requestArray from Alamofire.request instead of request
Alamofire.request(requestArray)
manager.request(url, method: .get, headers: AUTH_HEADER).responseJSON { response in
switch response.result {
case .success:
//whatever you want to do in succes
case .failure(let error):
if let del = self.delegate {
//do what you want
}
print(error)
}
}

Related

How to send a JSON body in a get request with Alamofire

I'm facing a problem since 3 weeks now, I'm using an API pretty particular which need a JSON object as body in a GET request. And I think that it's the main problem
I tried to custom my encoding with ParameterEncoding thanks the Alamofire documentation and all the help provide in Stack Overflow and still no success.
When I make my request with Postman or with curl in my terminal, there is no problem but when I develop in swift with Alamofire, I get an internal error 500 or nothing passed in my response (when I set my parameter in my request function with the keyword encoding : JSONEncoding.default).
Here is the curl exemple :
curl -X GET https://blih.epitech.eu/user/repositories
-H 'Content-Type: application/json'
-d '{"user": account, "signature": password}'
Here is the sample of my code :
/// swift 5
let userString = #"{"user":"\#(account)","signature":"\#(signaturePassword)"}"#
let urlString = "https://blih.epitech.eu/repositories"
Alamofire.request(urlString, method: .get, parameters: [:], encoding: JSONStringArrayEncoding.init(string: userString), headers: nil)
.responseJSON { (response) in
debugPrint(response)
}
The 'JSONStringArrayEncoding' is a structure with my Custom Encoding :
struct JSONStringArrayEncoding: ParameterEncoding {
private let myString: String
init(string: String) {
self.myString = string
}
func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
var urlRequest = try urlRequest.asURLRequest()
let data = Data(myString.utf8)
if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil {
urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
}
urlRequest.httpBody = data
return urlRequest
}
}
I expect to have a json Array when the request is successsful :
{
"message": "Listing successful",
"repositories": {
"aaaa": {
"uuid": "e3a6bea1-c581-5fde-a3a8",
"url": "https://blih.epitech.eu/repository/aaa"
}
}
}
But I get an internal error 500.
Thank you in advance for your help.
Just replace JSON.encoding -> URLEncoding
Alamofire.request(path,method: .get, parameters: params, encoding: URLEncoding.default, headers: nil)
As you have mentioned that, your request is working using postman or curl in terminal. Below is the result I'm getting
As pointed by #Glenn, result of visiting browser with url blih.epitech.eu/user/repositories show result like below
I believe, there is something wrong with the url you're requesting to.
EDITED:
See the below image to see the why it is working with curl
Try your request as post once and add content-type = application/x-www-form-urlencoded I am not sure but it might help.
Try this:
let url = "https://blih.epitech.eu/user/repositories"
let param = ["user":"asdfdsf",
"signature":"password"]
if let jsonData = try? JSONEncoder().encode(param) {
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = HTTPMethod.post.rawValue
request.setValue("application/json; charset=UTF-8", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData
Alamofire.request(request).responseJSON {
(response) in
debugPrint(response)
}
}
OUTPUT:
{
error = "Bad token";
}

How to send form-data body with Alamofire [duplicate]

This question already has answers here:
Send POST parameters with MultipartFormData using Alamofire, in iOS Swift
(13 answers)
Closed 5 years ago.
I want to make a request wit Alamofire like this:
postman request
As you can see, i have a parameter called "data" and its value is a Json,
How can i do that using Alamofire?
I have tried with parameters, but doesnt wotk
Alamofire.request(urlservice, method: .post, parameters: ["data": parameters], encoding: JSONEncoding.default, headers: nil).responseJSON { response in
Any suggestions?
UPDATE
Here is my code
var arrayProducts = [[String: String]]()
let product: [String: String] = ["qty": self.txtQty.text!, "precio": self.productPrice, "product_id": self.productId]
arrayProducts.append(product)
let parameters = [
"products": arrayProducts,
"address": self.userInfo["userAddress"]!,
"latitude": "6.157738",
"longitude": "-75.6144665",
"id": 1,
"name": self.userInfo["userName"]!,
"cellphone": self.userInfo["userPhone"]!,
"emei": "23456resdfty"
] as [String : Any]
Alamofire.request(urlservice, method: .post, parameters: ["data": parameters], encoding: JSONEncoding.default, headers: nil).responseJSON { response in
when you have an Any Data as paremeter, you should sent the URLRequest to Alamofire, it supports Any as body
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try! JSONSerialization.data(withJSONObject: parameters, options: [])
Alamofire.request(request)
.responseString { (response) in
// to do anything
}
Here is an example 4 you, the CURL statement an example of what it is doing.
Note token referenced here is a shared secret, obviously not stuff to post to SO :) bags of print statements in here so that you can see what going on/wrong :)
func files_download(sourcePath: String) {
// curl -X POST https://content.dropboxapi.com/2/files/download
// --header "Authorization: Bearer ab-XXX"
// --header "Dropbox-API-Arg: {\"path\": \"/acme101/acme1/acme.png\"}"
var headers:HTTPHeaders!
let subPart: Dictionary = ["path":sourcePath]
do {
let data = try JSONSerialization.data(withJSONObject: subPart, options: [])
let dataString = String(data: data, encoding: .utf8)
headers = ["Authorization": "Bearer " + token, "Dropbox-API-Arg": dataString!]
} catch {
print("Oh fudge")
}
Alamofire.request("https://content.dropboxapi.com/2/files/download", method: .post, encoding: JSONEncoding.init(options: []), headers: headers).responseData(completionHandler: {feedback in
guard feedback.result.value != nil else {
print("Error: did not receive data", //rint("request \(request) feedback \(feedback)"))
return
}
guard feedback.result.error == nil else {
print("error calling POST on list_folder")
print(feedback.result.error)
return
}
if let JSON = feedback.result.value {
print("JSON: \(JSON)")
let dataString = String(data: JSON, encoding: .utf8)
print("JSON: \(JSON) \(String(describing: dataString))")
}
if let IMAGE = feedback.result.value {
print("downloaded \(sourcePath) \(sharedDataAccess.currentSN)")
sharedDataAccess.fnData(index2seek: sharedDataAccess.currentSN, fnData: feedback.result.value! as Data)
NotificationCenter.default.post(name: Notification.Name("previewPane"), object: nil, userInfo: nil)
}
})
}

How to successfully pass string array as parameter alamofire

I have an endpoint that accepts a string array as parameter but I can't get it working with alamofire.
I test my endpoint with postman and it works fine, even in the browser, but with alamofire it fails and just returns the whole thing (as if I didn't put any parameter).
func getQuotes(String url){
//THIS CALL IS NOT WORKING. PARAMETERS ARE NOT SENT PROPERLY - FIX
let stringArray : [String] = ["4250_XSAU", "Test"]
let getQuoteParameters : Parameters = [
//"internal_symbols": stockInternalSymbols
"internal_symbols" : stringArray
]
print("attempting to get quotes on utility queue")
Alamofire.request(url, parameters: getQuoteParameters).responseJSON{ response in
print(response)
/* if (response.result.value != nil){
let jsonResponse = JSON(response.result.value!)
print(jsonResponse)
}
*/
}
}
Am I doing something wrong? When I go to url + "?internal_symbols=["4250_XSAU","Test"] on my browser, or postman, it works just fine.
I also tried setting my "getQuoteParamaters" variable as
let getQuoteParameters : Parameters = [
"internal_symbols" : ["4250_XSAU", "Test"]
]
but it doesn't work neither... it should be the same thing.
Just to clarify, this request ignores completely my parameters, when it should send the array to my backend.
You can simply pass your string array in converting it into a JSON format.Like in the sample code given below:
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let values = ["06786984572365", "06644857247565", "06649998782227"]
request.httpBody = try! JSONSerialization.data(withJSONObject: values)
Alamofire.request(request)
.responseJSON { response in
// do whatever you want here
switch response.result {
case .failure(let error):
print(error)
if let data = response.data, let responseString = String(data: data, encoding: .utf8) {
print(responseString)
}
case .success(let responseObject):
print(responseObject)
}
}
My solution in Swift 3:
let text: [String] = ["location.branches.longitude", "location.branches.latitude"]
let params: Parameters = [
"_source": text
]
Try by add encoding standard in your request, like JSONEncoding.default
func getQuotes(String url){
//THIS CALL IS NOT WORKING. PARAMETERS ARE NOT SENT PROPERLY - FIX
let stringArray : [String] = ["4250_XSAU", "Test"]
let getQuoteParameters : Parameters = [
//"internal_symbols": stockInternalSymbols
"internal_symbols" : stringArray
]
print("attempting to get quotes on utility queue")
Alamofire.request(url, method: .post, parameters: getQuoteParameters, encoding: JSONEncoding.default).responseJSON{ response in
print(response)
/* if (response.result.value != nil){
let jsonResponse = JSON(response.result.value!)
print(jsonResponse)
}
*/
}
Thanks.

Alamofire not sending the current headers (swift)

I keep getting "error_type":"OAuthException","code":"41" when I using alamofire or even when i made it through to the server I got data from before header's authorisation. I think it keep sending same header, how to make sure that alamofire send the current headers?
let headers = ["Authorization" : "\(AccessToken) \(TokenType)"]
print(headers)
Alamofire.request(.GET, "url/profile/", headers: headers, encoding: .JSON).responseJSON { response in
switch response.result {}
EDIT
First, I use login API
let parameters = [
"client_id": "\(Constant.clientId)",
"client_secret": "\(Constant.clientSecret)",
"response_type": "\(Constant.responseType)",
"scope" : "\(Constant.scope)",
"redirect_uri": "\(Constant.redirect)",
"email": "\(email!)",
"password": "\(pass!)"
]
print(parameters)
Alamofire.request(.POST, "http://url/login/", parameters: parameters, encoding: .JSON).responseJSON { response in
switch response.result {
case .Success:
if let value = response.result.value {
let json = JSON(value)
print("JSON: \(json)")
let accessToken = json["access_token"].string!
let refreshToken = json["refresh_token"].string
let tokenType = json["token_type"].string!
let expiresIn = json["expires_in"].string
}
And then, I use accessToken and tokenType for authorization
if(refreshToken != nil)
{
let headersCust = ["Authorization" : "\(accessToken) \(tokenType)"]
print(headersCust)
Alamofire.request(.GET, "http://goodies.co.id/api/v1/customer/profile/", headers: headersCust, encoding: .JSON).responseJSON { response in {}
Usually this problem is caused by Redirection. Using some networking debugging tool like Proxyman helps you to understand if this is a case; if so :
this is Alamofire 5(AF 5) solution:
let headers: [String:String] = [...]
let params: [String: Any] = [...]
let url = URL(...)
let redirector = Redirector(behavior: Redirector.Behavior.modify({ (task, urlRequest, resp) in
var urlRequest = urlRequest
headers.forEach { header in
urlRequest.addValue(header.value, forHTTPHeaderField: header.key)
}
return urlRequest
}))
//use desired request func of alamofire and your desired enconding
AF.request(url, method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers)
.responseJSON { response in
//handleDataResponse...
}.redirect(using: redirector)
I hope you are using the latest Alamofire so here is the code for .GET Request:
let headers = [
"Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==",
"Content-Type": "application/x-www-form-urlencoded"
]
Alamofire.request(.GET, "https://httpbin.org/get", headers: headers)
.responseJSON { response in
debugPrint(response)
}
Reference: https://github.com/Alamofire/Alamofire
Try this out! And make sure you are sending the proper headers.

How to create and send the json data to server using swift language

I'm new to IOS development and I have started with the swift language.
I'm trying to get the value from two text fields and convert those two text fields into json and send that json to the server receive.php.
lets concider that tow text fields are
- name
- pass
how do i create a Json & send that to server when a button is clicked ?
By using http POST method with URLSession. Let's say you are calling submitAction method on the press of the login button
Swift 4 and above
#IBAction func submitAction(_ sender: UIButton) {
//declare parameter as a dictionary which contains string as key and value combination. considering inputs are valid
let parameters: [String: String] = ["name": nametextField.text, "password": passwordTextField.text]
//create the url with URL
let url = URL(string: "http://myServerName.com/api")! //change the url
//create the session object
let session = URLSession.shared
//now create the URLRequest object using the url object
var request = URLRequest(url: url)
request.httpMethod = "POST" //set http method as POST
do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) // pass dictionary to nsdata object and set it as request body
} catch let error {
print(error.localizedDescription)
}
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
//create dataTask using the session object to send data to the server
let task = session.dataTask(with: request, completionHandler: { data, response, error in
guard error == nil else {
return
}
guard let data = data else {
return
}
do {
//create json object from data
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
print(json)
// handle json...
}
} catch let error {
print(error.localizedDescription)
}
})
task.resume()
}
Swift 3,Swift 4
The method above is very in-efficient, use alamofire instead
https://github.com/Alamofire/Alamofire
get email and passwoord from textfield
#IBAction func submitAction(sender: AnyObject) {
let email= emailfield.text
let password= emailfield.text
let parameters: Parameters = [
"email": email,
"password": password
]
Alamofire.request("https://httpbin.org/post", method: .post, parameters: parameters) }
or here is an example
let parameters: Parameters = [
"foo": "bar",
"baz": ["a", 1],
"qux": [
"x": 1,
"y": 2,
"z": 3
]
]
// All three of these calls are equivalent
Alamofire.request("https://httpbin.org/post", method: .post, parameters: parameters)
Alamofire.request("https://httpbin.org/post", method: .post, parameters: parameters, encoding: URLEncoding.default)
Alamofire.request("https://httpbin.org/post", method: .post, parameters: parameters, encoding: URLEncoding.httpBody)
// HTTP body: foo=bar&baz[]=a&baz[]=1&qux[x]=1&qux[y]=2&qux[z]=3
For those having issues getting Alamofire.request to work, use AF instead of Alamofire. For example:
AF.request("https://httpbin.org/post", method: .post, parameters: parameters)
From the docs:
Previous versions of Alamofire's documentation used examples like
Alamofire.request(). This API, while it appeared to require the
Alamofire prefix, in fact worked fine without it. The request method
and other functions were available globally in any file with import
Alamofire. Starting in Alamofire 5, this functionality has been
removed and instead the AF global is a reference to Session.default.
This allows Alamofire to offer the same convenience functionality
while not having to pollute the global namespace every time Alamofire
is used and not having to duplicate the Session API globally.
Similarly, types extended by Alamofire will use an af property
extension to separate the functionality Alamofire adds from other
extensions.

Resources