Alamofire always enter on Failure status - swift

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.

Related

AFDataResponse : Convert data to JSON format Swift 5

I implemented the following code
AF.request(url, method: .post, parameters: parameter, encoding: JSONEncoding.default).responseData(completionHandler: {response in
print(response)
switch response.result {
case .success:
print(response.result)
let alertVC = self.alertservices.alert(title: "Add Recipe : Basic Level", message: "Your basic level recipe details has been submitted successfully!", cancelTitle: "Cancel", submitTitle: "Ok", alertimage: "recipes"){
self.detailContainerView.isHidden = false
}
self.present(alertVC,animated: true)
break
case .failure :
let alertVC = self.alertservices.alert(title: "Add Recipe : Basic Level", message: "Something went wrong. Please try again!", cancelTitle: "Cancel", submitTitle: "Ok", alertimage: "recipes"){
}
self.present(alertVC,animated: true)
break
}
})
If I use .responseData then I get the this output success(118 bytes) instead of what is mentioned below. But the actual response which I get when I place the values in the postman is
{
"response": "success",
"status": 0,
"recipe_id": 10422
}
If I use .responseJSON then the following error is shown at the console.
["recipe_preparation_time": "00:10:00", "recipe_title": "test recipe", "recipe_category": "2", "veg_status": "1", "recipe_food_type[]": [1, 3], "type": "3", "recipe_cooking_time": "00:10:00", "recipe_country": "", "customer_id": "5", "added_by": "5", "difficulty_level": "1"]
success({
error = {
"recipe_food_type" = (
"The recipe food type field is required."
);
};
message = "Validation Error";
status = 406;
})
Can anyone help me to solve this?
As #Frankenstein mentioned its good to create Codable struct. But when you are using Alamofire you can use:
AF.request(url).validate().responseDecodable(of: Response.self) { response in
// and then on response.value you have your response struct
}
Create a Codable resposne struct, and decode using JSONDecoder():
struct Response: Codable {
let response: String
let status, recipeId: Int
enum CodingKeys: String, CodingKey {
case response, status
case recipeId = "recipe_id"
}
}
Add this format for you request:
AF.request(url, method: .post, parameters: parameter, encoding: JSONEncoding.default).validate().responseDecodable(of: Response.self) { response in

Print data from Alamofire request, swift

I made this request:
func AlamofireGetCode()
{
let username: String = searchTextField.text!
var url:String!
url = "https:// ... "
AF.request(url, method: .get, encoding: JSONEncoding.default)
.responseJSON { response in
switch response.result {
case .success:
debugPrint(response)
case .failure(let error):
fatalError("\(error)")
}
}
}
And I'm getting this response with different fields:
[Result]: success({
"incomplete_results" = 0;
items = (
{
"username" = " ... "
...
How do I get some specific field like "username" in Swift?
I would like to have all the username of all the user and store them, could you help me?
You need to provide a type to parse the JSON response into. Using a site like quicktype.io can generate one from your JSON, but any Decodable type will do. Then you can use Alamofire's responseDecodable handler to parse your response.
AF.request(url).responseDecodable(of: TypeToParse.self) { response in
debugPrint(response)
}
Paste your response in https://jsonparseronline.com/ to see the structure of the object. It will show you all the keys and values that you can access using subscripts.

Alamofire not getting full response

I'm trying to fetch data from a GET request using Alamofire in Swift. There's an issue where it's not getting the full response from the request. The response is an array with nested arrays some String and some [String:Any]. I've none of the [String:Any] gets pulled in using Alamofire and think this is a serious bug. Postman shows the nested array values but not Alamofire.
The request
Alamofire.request(request.getFullUrl(param: paramsForUrl), method: request.getMethodType(), parameters: data, encoding: request.getEncoding(), headers: headers).validate(statusCode: 200..<500).responseJSON { response in }
What a typical response should look like
{
"uuid": "787FDS8-FS7FS7DG9-FSD789FCS98",
"name": "Show time",
"views_count": 0,
"comments_count": 0,
...
"events": [
{
"uuid": "f69a358e-9a1e-427c-a158-95dfc8c54ed7",
"name": "Test",
...
},
{
"uuid": "8993b639-f6c9-4d20-b8a9-c43c73a9828b",
"name": "Test 2",
...
},
...
]
"times: [
{
"name: "test time 1",
"clock: "Face"
},
{
"name": "test time 2",
"clock: "Back"
}
]
}
What's missing
Anything inside nested arrays: events, times. If I have a simple array of String then Alamofire gets these. It doesn't show anything nested and this is with both printing response.result.value and JSON decoding the response and accessing events directly. It doesn't see events or times.
Thanks for your help.
May be your JSON is not valid. To check that try changing responseJSON to responseString and see if it prints all the data e.g.
Alamofire.request(url ,method: .get ,parameters: data).validate().responseString{ response in
switch response.result{
case .success:
let s = response.result.value ?? "nil"
print("API Response: \(s)")
case .failure:
debugPrint(response)
}
}
If the above is printing all the data from your server than you need to fix the service
Delete .validate(statusCode: 200..<500) and try again.
Alamofire.request(url ,method: .get ,parameters: parameter).responseJSON{ response in
switch response.result{
case .success:
let value = response.result.value ?? "nil"
print("API Response: \(value)")
case .failure:
print("error")
}
}

Alamofire responseSerializationFailed

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)

Getting JSON array with Alamofire + SwiftyJSON

I'm really new to Swift, sorry if this is a dumb question... there seem to be many questions about this but none of them use the latest version of Alamofire
Alamofire.request(.GET, url)
.responseJSON { response in
let json = JSON(response.data!)
debugPrint(json)
self.delegate?.didReceiveAPIResults(json)
}
And the delegate's didReceiveAPIResults method
func didReceiveAPIResults(results: JSON) {
dispatch_async(dispatch_get_main_queue(), {
self.tableData = results["items"].arrayObject!
self.appsTableView!.reloadData()
})
}
Here's the JSON response:
{
"items": [
{
"id": 1,
"name": "Sample 1"
},
{
"id": 2,
"name": "Sample 2"
}
]
}
I expect the debugPrint to print something similar to that JSON, but instead it just prints unknown
If I debugPrint response.data by itself, it appears to be encoded...
Optional(<7b226461 7461223a 5b7b2269 64223a36 2c226e61 6d6522......
Then my results["items"].arrayObject! line has this error:
fatal error: unexpectedly found nil while unwrapping an Optional value
Rather than grabbing response.data, I'd suggest grabbing response.result.value. When you do responseJSON, Alamofire does the JSON parsing for you, and you should feel free to just grab this parsed object.
Alamofire.request(.GET, url)
.responseJSON { response in
if let value = response.result.value {
let json = JSON(value)
self.delegate?.didReceiveAPIResults(json)
}
}