Alamofire POST request not working - ios

let requestDictionary : [String: AnyObject] = [
"sm_username" : name as AnyObject,
"sm_password" : pass as AnyObject
]
let headers = [
"Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==",
"Content-Type": "application/x-www-form-urlencoded",
"Krikor": "Krikor"
]
Alamofire.request(baseURL+"login", method: .post, parameters: requestDictionary, encoding: JSONEncoding(options: []),headers: headers
).responseJSON{ response in
debugPrint(response)
print("krirkrkdkd")
print(response)
}
So basically, the headers are not being passed. Neither encoded parameters. Why? And how to fix?

Kiikor,
Here is a working example of a alamofire request in swift, including the encoding.
func files_download(sourcePath: String) {
let defaults = UserDefaults.standard
if let name = defaults.string(forKey: "dropBoxAuth")
{
token2Save = name
}
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 " + token2Save, "Dropbox-API-Arg": dataString!]
} catch {
print("error")
}
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", print("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 {
let dataString = String(data: JSON, encoding: .utf8)
}
if let IMAGE = feedback.result.value {
sharedDataAccess.fnData(index2seek: 0, fnData: feedback.result.value! as Data)
NotificationCenter.default.post(name: Notification.Name("nextACtion"), object: nil, userInfo: nil)
}
})

Related

Issue while sending array of dictionary in swift

I am creating array of dictionaries and then passing that in paramDictionary and sending to server but I get responseStatus code 422. I am using Alamofire 5.
Here is the structure of param which I have to send and it successfully working on postman but in app it is always fails
{"check_in": [{"check_in_at":"2020-02-26 03:23:44", "gps_coordinates":"3.1697998046875,101.61672197976593"},
{"check_in_at":"2020-02-26 03:23:45","gps_coordinates":"3.1697998046875,101.61672197976593"}]}
Here is my code
func postCheckInApi(viewController: UIViewController,
completion:#escaping (_ result:SuccessErrorData)->(),
errorHandler:#escaping (_ result:Error,_ statusCode:Int?)->()//error handler
) {
let url = KCheckin
let geoArr = Constant.getSearchLocationHistory() ?? [GeoTaggingEntity]()
var arr = [[String: String]]()
for i in geoArr{
let dict: [String : String] = ["gps_coordinates" : i.gps_coordinates ?? "", "check_in_at" : i.check_in_at]
arr.append(dict)
}
let parameterDictionary = ["check_in": arr] as [String : Any]
print(parameterDictionary)
let headers: HTTPHeaders = [
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": Constant.getBearerToken() ?? ""
]
AF.request(url, method: .post, parameters: parameterDictionary, headers: headers).responseData { response in
switch response.result{
case.success(let data):
do{
let jsonData = try JSONDecoder().decode(SuccessErrorData.self, from: data)
print("Success")
completion(jsonData)
}
catch{
//viewController.navigationController?.popToRootViewController(animated: true)
}
case .failure(let error):
print(error)
}
}
}
You can not add Array as parameter object to your paramDictionary. You need to covert your Array to json string and then add it to you paramDictionary.
For that use below Collection extension to convert your Array to Json String
extension Collection {
func json() -> String? {
guard let data = try? JSONSerialization.data(withJSONObject: self, options: []) else {
return nil
}
return String(data: data, encoding: String.Encoding.utf8)
}
}
How To Use
let jsonStr = yourArray.json()
add this jsonStr to your paramDictionary

Swift 4 - Alamofire post request with httpbody

I have this Alamofire post request like so:
var jsonArrayOfDictionaries = [[AnyHashable: Any]]()
let user = appDelegate.username
let password = appDelegate.password
let url = webservice + "PostTasks"
let credential = URLCredential(user: user!, password: password!, persistence: .forSession)
let headers = ["Accept": "application/json;odata=verbose", "Content-type": "application/json;odata=verbose"]
let jsonData: Data? = try? JSONSerialization.data(withJSONObject: jsonArrayOfDictionaries, options: .prettyPrinted)
print(jsonData!)
//request.httpBody = jsonData
Alamofire.request(url, method: .post, headers: headers).authenticate(usingCredential: credential).responseJSON {
(response) in
switch response.result {
case .success:
if let value = response.result.value {
print(value)
OperationQueue.main.addOperation({
completion(true)
})
}else{
print("There is error in the server response")
completion(false)
}
case .failure (let error):
print("The NTLM request error is: ", error.localizedDescription)
completion(false)
}
}
My question is how do I add the jsonData variable to the httpbody of this request? I have looked into this issue and all the solutions appear to be old. Please help!
This is how jsonArrayOfDictionaries is getting populated:
var jsonArrayOfDictionaries = [[AnyHashable: Any]]()
for i in 0..<cellHolder.count {
var jsonDict = [AnyHashable: Any]()
jsonDict["scheduleTaskID"] = cellHolder[i].scheduleTaskID
jsonDict["task"] = cellHolder[i].task
jsonDict["scheduledDate"] = cellHolder[i].scheduledDate
jsonDict["actualDate"] = cellHolder[i].actualDate
jsonDict["finishedDate"] = cellHolder[i].finishedDate
jsonDict["selected"] = (cellHolder[i].selected) ? 1 : 0
jsonDict["completedBy"] = appDelegate.username
jsonDict["sortOrder"] = cellHolder[i].sortOrder
jsonArrayOfDictionaries.append(jsonDict)
jsonDict = [AnyHashable: Any]()
}
Its in a loop and gets appended.
1. Change
let jsonData: Data? = try? JSONSerialization.data(withJSONObject: jsonArrayOfDictionaries, options: .prettyPrinted)
to
let jsonData = try JSONSerialization.jsonObject(with: jsonArrayOfDictionaries, options: []) as? [String : Any]
2. Add jsonData to your request
Alamofire.request(url, method: .post, headers: headers, parameters: jsonData).authenticate(usingCredential: credential).responseJSON {

JSON data not parsing using with Alamofire in swift3

I have to parse json using alamofire
before am using json session its working fine getting data from the json. now am try to parse json using alamofire.
this is the code parse the json using json, this code working fine
func auth(_ email:String,password:String) {
var request = URLRequest(url:AppConstants.apiURLWithPathComponents("usersignin"))
let session = URLSession.shared
request.httpMethod = "POST"
let bodyData = "email=\(email)&passCode=\(password)&deviceType=iOS&deviceId=\(deviceToken)"
request.httpBody = bodyData.data(using: String.Encoding.utf8);
let task = session.dataTask(with: request, completionHandler: { (data, response, error) in
do {
if data != nil {
if let jsonData = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary {
errorCode = String(describing: jsonData["errorCode"]!)
msg = jsonData["msg"] as! String
print(errorCode)
print(jsonData)
if(errorCode == "1"){
DispatchQueue.main.async(execute: {
self.activityIndicator.stopAnimating()
})
} else {
self.name = jsonData.value(forKey: "name") as! String
if let kidsURLDetails = jsonData["kidsURLDetails"] as? NSArray {
for i in 0 ..< kidsURLDetails.count {
if kidsURLDetails[i] is NSDictionary {
let url = kidsURLDetails[i] as? NSDictionary
self.urls.append((url?["url"]) as! String)
}
}
}
self.serverURL = self.urls.joined(separator: ",")
print("ServerURL \(self.serverURL)")
let prefs:UserDefaults = UserDefaults.standard
prefs.setValue(self.name, forKey: "NAME")
DispatchQueue.main.async(execute: {
UIApplication.shared.endIgnoringInteractionEvents()
let controllerId = "NavID"
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let initViewController: UIViewController = storyboard.instantiateViewController(withIdentifier: controllerId) as UIViewController
self.present(initViewController, animated: true, completion: nil)
})
}
}
} else {
}
} catch let err as NSError {
print("JSON Error \(err)")
}
})
task.resume()
}
in above code I used post method with passing parameters, when I am trying post method with parameter passing in almofire am getting error "Extra argument 'method' in call", username and password coming from textfield so after enter the email and password I have pass the parameters using post method.
this is the code I will implemented in to alamofire json parse
var request = URLRequest(url:AppConstants.apiURLWithPathComponents("usersignin"))
let bodyData = "email=\(username)&passCode=\(passcode)&deviceType=iOS&deviceId=123456"
let deviceId = "1234"
let params: [String: Any] = ["email": username, "passCode": passwordstring, "deviceType": "IOS","deviceId":deviceId]
Alamofire.request(request, method: .post, parameters: params, encoding: JSONEncoding.default, headers: nil)
.responseJSON { response in
print(response.result.value as Any) }
if I can try this code working
Alamofire.request("http://www.kids.com/rk/api/usersignin?email=demo#kidsapp.com&passCode=123456&deviceType=&deviceId=", method: .post, parameters: nil, encoding: JSONEncoding.default, headers: nil)
.responseJSON { response in
print(response.result.value as Any) }
how can I parse the json post method passing parameters using alamofire. where I did mistake pls help me
You are passing wrong type in 1 param in call it should be URLConvertible(string or URL) not URLRequest. try below code.
let params: [String: Any] = ["email": username, "passCode": passwordstring, "deviceType": "IOS","deviceId":deviceId]
let url = URL(string: "http://www.kids.com/rk/api/usersignin")!
Alamofire.request(url, method: .post, parameters: params, encoding: JSONEncoding.default, headers: nil)
.responseJSON { response in
}
____________Edit___________
here header is post request headers(if any) or nil
let params: [String: Any] = ["email": username, "passCode": passwordstring, "deviceType": "IOS","deviceId":deviceId]
let urlString = "http://www.kids.com/rk/api/usersignin"
guard let url = URL(string: urlString), var request = try? URLRequest(url: url, method: .post, headers: header) else{
//
return
}
request.httpBody = params.map{ "\($0)=\($1)" }.joined(separator: "&").data(using: .utf8)
Alamofire.request(request).responseJSON { response in
}
If you need to send the parameters in url with post request you should use URLEncoding.default encoding rather than JSONEncoding.default. JSONEncoding is used when you need to send JSON data as body with content type application/json.
Change your code like:
Alamofire.request(url, method: .post, parameters: params, encoding: URLEncoding.default, headers: nil).responseJSON { response in
print(response.result.value as Any)
}
Or you can remove encoding parameter as URLEncoding is the default encoding of Alamofire.
// URL
let urlString = “URL_Here”
var params = [String: Any]()
//Contruct your params
params = ["email": username, "passCode": passwordstring, "deviceType": "IOS","deviceId":deviceId]
// Request
Alamofire.request(urlString, method: .post, parameters: params, encoding: JSONEncoding.default, headers: nil)
.validate(statusCode: 200..<300)
.responseJSON { response in
if (response.result.error == nil) {
let value = response.result.value
print(value)
}
else {
let errorString = response.result.error
print(errorString)
}
}

How to send json as parameter iOS swift?

I want to send following object as body parameter. But serialization is failing:
{
"StartAddress":"Colombo",
"EndAddress":"Kandy",
"DepartureAddress":"Kollupitiya, Colombo",
"ArrivalAddress":"Peradeniya, Kandy",
"CreatedDate":"2017-07-30",
"Date":"2017-07-30",
"Time":"2017-07-30",
"IsLadiesOnly":true,
"IpAddress":"fe80::8638:38ff:fec8:ea50%wlan0",
"Country":"Srilanka",
"VehicleId":"1129",
"StartLocation":[
6.9270974,
79.8607731
],
"EndLocation":[
7.2916216,
80.6341326
],
"Points":"k}gi#y{lf",
"Route":{
"Bounds":{
"NorthEast":[
7.2916216,
80.6341326
],
"SouthWest":[
6.9270974,
79.8607731
]
},
"Legs":[
{
"LegId":1,
"Distance":14904,
"Duration":1941,
"StartAddress":"Colombo",
"EndAddress":"Kadawatha",
"StartLocation":[
6.9270974,
79.8612478
],
"EndLocation":[
7.0011125,
79.95000750000001
],
"Ancestors":[
],
"Price":745
},
{
"LegId":2,
"Distance":63040,
"Duration":6209,
"StartAddress":"Kadawatha",
"EndAddress":"Kegalle",
"StartLocation":[
7.0011125,
79.95000750000001
],
"EndLocation":[
7.251436200000001,
80.3466076
],
"Ancestors":[
"Colombo"
],
"Price":3152
},
{
"LegId":3,
"Distance":38990,
"Duration":4430,
"StartAddress":"Kegalle",
"EndAddress":"Kandy",
"StartLocation":[
7.251436200000001,
80.3466076
],
"EndLocation":[
7.2901864,
80.6338425
],
"Ancestors":[
"Colombo",
"Kadawatha"
],
"Price":1950
}
]
},
"TotalPrice":"5847.0",
"SeatCount":1,
"Detour":1,
"Luggage":2,
"DetoursDescription":"10 Minutes",
"LuggageDescription":"Small Luggage",
"Notes":"new ride"
}
when I try to serialize it before send it gives an error:
'NSInvalidArgumentException', reason: '*** +[NSJSONSerialization
dataWithJSONObject:options:error:]: Invalid top-level type in JSON
write'
func synchronusPostRequstWithHeadersJson(apiMethod:String, params:JSON, headers:[ String: String]) -> ResultModel {
let resultModel = ResultModel()
//create the url with URL
let url = URL(string: BASE_URL + apiMethod )!
let session = URLSession.shared
//// **** HERE IT FAILING *****////
let jsonData = try? JSONSerialization.data(withJSONObject: params)
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = jsonData
for item in headers {
request.addValue(item.value, forHTTPHeaderField: item.key)
}
let semaphore = DispatchSemaphore(value: 0)
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
if(error != nil){
resultModel.ErrorType = .NO_INT
resultModel.JsonReslut = JSON.null
}else{
if let resp = response as? HTTPURLResponse{
if(resp.statusCode == 200){
if let jsonResult = JSON(data) as? JSON {
resultModel.ErrorType = .NO_ERROR
resultModel.JsonReslut = jsonResult
}
}else{
if let jsonResult = JSON(data) as? JSON {
resultModel.ErrorType = .SEREVR_ERROR
resultModel.JsonReslut = jsonResult
}else{
resultModel.ErrorType = .SEREVR_ERROR
resultModel.JsonReslut = JSON.null
}
}
}
}
semaphore.signal()
})
task.resume()
_ = semaphore.wait(timeout: DispatchTime.distantFuture)
return resultModel
}
How can i send that request?. Is it possible with alamofire?
Using Almofire you can achieve this as
let params: [String: Any] = [
"StartAddress":"Colombo",
"EndAddress":"Kandy",
"DepartureAddress":"Kollupitiya, Colombo",
"StartLocation":[
6.9270974,
79.8607731
],
"EndLocation":[
7.2916216,
80.6341326
],
] //Do check your dictionary it must be in correct format
Alamofire.request("yourUrl", method: .post, parameters: params, encoding: JSONEncoding.default)
.responseJSON { response in
print(response)
}
try using:
let session = Foundation.URLSession.shared
let url = URL(string: "Your server url")
var request = URLRequest(url : url!)
request.httpMethod = "POST"
let params :[String:Any] = ["name":"yuyutsu" as Any,"rollno":12 as Any] //Add your params
do {
let jsonData = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData
session.dataTask(with: request, completionHandler: { data, response, error in
OperationQueue.main.addOperation {
guard error == nil && data != nil else { // check for fundamental networking error
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
// print("response = \(response)")
}
let responseString = String(data: data!, encoding: String.Encoding.utf8)
print("responseString = \(responseString!)")
if let responsedata = responseString!.data(using: String.Encoding.utf8)! as? Data{
do {
let jsonResult:NSDictionary = try JSONSerialization.jsonObject(with: responsedata, options: []) as! NSDictionary
print("Get The Result \(jsonResult)")
if error != nil {
// print("error=\(error)")
}
if let str = jsonResult["success"] as? NSNull {
print("error=\(str)")
}
else {
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("Response string : \(responseString)")
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
}
}) .resume()
}catch {
// print("Error -> \(error)")
}
hope this might help you out.
Creating JSON parameters to send it as a post body:
Function:
//MARK:- Create JSON String
func createJSONParameterString(postBody:AnyObject) -> String {
if let objectData = try? JSONSerialization.data(withJSONObject: postBody, options: JSONSerialization.WritingOptions(rawValue: 0)) {
let objectString = String(data: objectData, encoding: .utf8)
return objectString ?? ""
}
return ""
}
Usage:
var postBody = [AnyHashable:Any]()
postBody["device_id"] = "device_ID"
let parameters = createJSONParameterString(postBody: postBody as AnyObject)
print(parameters)
i have solved similar problem using Alamofire and SwiftyJson as follow
let call your object (data )
let json = JSON(data)
let Params :Dictionary = json.dictionaryObject!
and in Alamofire request
Alamofire.request(url, method: .post, parameters: Params , encoding: JSONEncoding.prettyPrinted, headers: nil)
//.validate(statusCode: 200..<300)
.responseJSON { response in
switch response.result
{
case .failure(let error):
case .success(let value):
}
it need to replace this "{ }" with "[ ]"
and alamofire and swift json handle that issue
ex:
[
{
"firstName" : " " ,
"lastName" : " "
},
{
"firstName" : " " ,
"lastName" : " "
}
]
change it to
[
[
"firstName" : " " ,
"lastName" : " "
],
[
"firstName" : " " ,
"lastName" : " "
]
]

Alamofire parameter encoding, dictionary within a dictionary

Want to send this to Alamofire using Swift...
curl -X POST https://content.dropboxapi.com/2/files/download
--header "Authorization: Bearer ab-xxx-x-x"
--header "Dropbox-API-Arg: {\"path\": "/acme101/acmeX100/acmeX100.001.png\"}"
But can't figure how to get the second --header you see here into the code? Tried several times with different combinations, but ...
JSON: 114 bytes Optional("Error in call to API function \"files/download\": Must provide HTTP header \"Dropbox-API-Arg\" or URL parameter \"arg\".")
I provided it, but not correctly evidently?
let subPart: NSDictionary = ["path": sourcePath]
let headers:HTTPHeaders = ["Authorization": "Bearer " + token2Save, "Dropbox-API-Arg": String(describing: subPart)]
Alamofire.request("https://content.dropboxapi.com/2/files/download", method: .post, encoding: JSONEncoding.init(options: []), headers: headers).responseData(completionHandler: {feedback in
Ureka!! THANK YOU Mr UB for giving me those tips. Found the solution.
let subPart: Dictionary = ["path":sourcePath]
do {
let data = try JSONSerialization.data(withJSONObject: subPart, options: [])
let dataString = String(data: data, encoding: .utf8)
headers = ["Authorization": "Bearer " + token2Save, "Dropbox-API-Arg": dataString!]
} catch {
print("crunch")
}
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", print("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) \(dataString)")
}
if let IMAGE = feedback.result.value {
sharedDataAccess.fnData(index2seek: 0, fnData: feedback.result.value! as Data)
NotificationCenter.default.post(name: Notification.Name("previewPane"), object: nil, userInfo: nil)
}
})

Resources