Alamofire responseSerializationFailed - swift

I am using Alamofire to make request in my swift app. All of my request were working 2 days ago and now only some of them are working. My API is working correctly, I get the correct response using Postman and in the Android version of my app.
Here is the request code
let headers: HTTPHeaders = [
"Authorization": "\(token)",
"Accept": "application/json"
]
Alamofire.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers).responseJSON(completionHandler: { (response) in
deactivateActivityIndicator()
if let json = response.result.value {
log.debug("User json: \(json)")
let user = Mapper<User>().map(JSON: JSON(json).dictionaryObject!)
self.delegate?.getRequestSuccessful(user!)
}
else{
self.delegate?.requestError("Error occurred getting response from API")
}
})
The JSON I am requesting from my API looks as follows:
{
"id": "1",
"email": "test#test.com",
"first_name": "Test",
"last_name": "Tester",
"role": 1,
"verified": true,
"edited": "2018-08-14T11:52:31.900Z",
"created": "2018-08-14T08:02:59.251Z"
}
I keep getting a 401 response as follows:
responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(Error
Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character
0." UserInfo={NSDebugDescription=Invalid value around character 0.}))
I have tried change from responseJSON to responseString like in the question here but it did not fix the problem

Please try with JSONEncoding.default . in place of URLEncoding.default in your existing code

I managed to fix the issue after a couple of days of searching and debugging. When entering the URL for the Alamofire request I was using the URL formatted like https:///www.test.com. I added an extra slash at the end as follows https:///www.test.com/
According to what I found, the request will get redirected to the correct URL and the headers are not sent along with the request. Thus explaining the 401 response (Unauthorized)

Related

Alamofire syntax for ecobee request

I'm trying to find the correct syntax for calling ecobee's API from Swift 4 using Alamofire.
Their cURL example:
curl -H "Content-Type: text/json" -H "Authorization: Bearer ACCESS_TOKEN" 'https://api.ecobee.com/1/thermostat?format=json&body=\{"selection":\{"selectionType":"registered","selectionMatch":"","includeRuntime":true\}\}'
The closest I've been to a solution is this
func doRequest() {
guard let url = URL(string: "https://api.ecobee.com/1/thermostat?format=json") else { return }
let parameters: Parameters = [
"selection": [
"selectionType": "registered",
"selectionMatch": ""
]
]
let headers: HTTPHeaders = [
"Content-Type": "text/json",
"Authorization": "Bearer \(core.accessToken)"
]
let req = AF.request(url, method: .get, parameters: parameters, encoding: JSONEncoding.default, headers: headers)
.responseJSON { response in
print("Error:", response.error?.localizedDescription ?? "no error")
print("Data:", String(data: response.data!, encoding: .utf8)!)
}
debugPrint(req)
}
When I run this, the call ultimately fails with status code 408, a server timeout.
When I change the HTTP method to use .post, the call completes, but the response is an internal status 3 with message "Update failed due to a communication error."
Can anyone help me figure out what I'm doing wrong before I waste another day trying to hack my way through it?
Ecobee's request format is a bit bizarre, as it uses form encoded parameters, but one of the values is a JSON encoded body. You'll have to do a little bit of prep work, as Alamofire doesn't naturally support something like this. This is just sample code, you'll need to do the work to make it safer.
First, encode the JSON parameters and get the String value:
let jsonParameters = ["selection": ["selectionType": "registered", "selectionMatch": ""]]
let jsonData = try! JSONEncoder().encode(jsonParameters)
let jsonString = String(decoding: jsonData, as: UTF8.self)
Then, create the actual parameters and headers values:
let parameters = ["format": "json", "body": jsonString]
let token = "token"
let headers: HTTPHeaders = [.authorization(bearerToken: token), .contentType("text/json")]
let url = URL(string: "https://api.ecobee.com/1/thermostat")!
And make the request:
AF.request(url, parameters: parameters, headers: headers).responseJSON { response in ... }

Alamofire POST request URL

Suppose i have a URL "http://aewfwfpi.staginwwedwfg.dewfewf.io/mobile/v1/network/station/10/timetablesss"
where 10 in the above URL is the stationId and can be any number .
How can i POST a request with changing parameter(StationId) in the URL using alamofire?
Should i add it in Parameter section?
Please help
Currently am calling it statically like below:-
Alamofire.request(
"http://aewfwfpi.staginwwedwfg.dewfewf.io/mobile/v1/network/station/10/timetablesss",
parameters:nil,
headers: nil)
var id = 123
var yourURL = "http://aewfwfpi.staginwwedwfg.dewfewf.io/mobile/v1/network/station/\(id)/timetablesss"
use \(variableName) to insert variables or constants in a string
Headers is where you specify the format of the content that you want to send and receive.
example of headers:
let headers: HTTPHeaders = [
"Accept": "application/json",
"Content-Type": "application/json"
]
Parameters is where you put the data that you want to send (POST)
example of parameters:
let pararameters: [String, Any] = [
"name": name as String,
"id": id as Int,
]
To do a POST request, add the parameters to the body of the request and not the url itself.
Something like below is what you must follow:
let parameters: Parameters = ["parameter-name": parameterValue]
let headers = ["Content-Type":"application/json"]
Alamofire.request("<your post url>",method: .post, parameters: parameters, encoding: JSONEncoding.default,headers: headers)
.responseJSON { response in
print(response)
// Do anything you like with the response here
}

POST request not working in swift3 with alamofire

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

Alamofire always enter on Failure status

I am trying to make a request with Alamofire and Swift 3.0 but it is always going to the failure status.
This is the code I have right now:
let str = "http://url/{\"user\":\"1\",\"pass\":\"1\"}"
let encodedUrl = str.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
Alamofire.request(encodedUrl!, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil).responseJSON { response in
switch(response.result) {
case .success(_):
print("Success")
break
case .failure(_):
print("Failure")
break
}
}
If I use the encodedUrl on Postman application I get the response well. It gives to me the following JSON:
[
{
"user": "1",
"name": "peter"
},
{
"user": "4",
"name": "andrew"
}]
What am I missing?
Thanks in advance!
Finally, it seems that I was retrieving an extra String out of the JSON because I used an echo on my API.
I could not see it because I had on Postman the option to show the response as JSON so the String was not being shown. I have changed it to HTML and then I was able to see the String.
Removing the extra String let me enter on the success status of Alamofire.

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
}