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")
}
}
Related
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
I'm parsing this json from a REST API with SwiftyJSON:
{
"status": {
"code": 201,
"description": "success"
},
"result": [
{
"id": "5951e8eee0207e049c339691",
......
}
]
}
After sending the request with Alamofire and getting the response is when I run into an issue:
case .success:
if let value = response.result.value {
let json = JSON(value)
print(json)
if json["status"]["code"].intValue == 201 {
self.jsonData = json["result"].arrayValue
self.mytableView.reloadData()
print("realoded tableView")
}else{
HUD.show(.error)
HUD.hide(afterDelay: 0.5)
HUD.flash(.label("message"), delay: 3.0){ _ in
print("fail message")
}
}
}
myTableView reloads the data, and the console shows the print message. However, the HUD is also showing a message, and the console logs the fail message.
P.S. I have also tried to compare as a string with json["result"]["code"].stringValue == "201". This does the same tableview update, but the hud is shown the hud is managed with PKHUD library.
I'm very new to Swift 3, and i have to do a GET request on my API. I'm using Alamofire, which uses Asynchronous functions.
I do exactly the same on my Android App, and the GET returns JSON data
This is my code in swift :
func getValueJSON() -> JSON {
var res = JSON({})
let myGroup = DispatchGroup()
myGroup.enter()
Alamofire.request(url_).responseJSON { response in
res = response.result.value as! JSON
print("first result", res)
myGroup.leave()
}
myGroup.notify(queue: .main) {
print("Finished all requests.", res)
}
print("second result", res)
return res
}
But i have a problem with the line "res = response.result.value" wich gives me the error : Thread 1 : signal SIGABRT
I really don't understand where the problem comes from, it was pretty hard to do a "synchronous" function, maybe i'm doing it wrong.
My objective is to store the result of the request in a variable that i return. Anyone can help ?
I'd recommend you to use Alamofire together with SwiftyJSON because that way you'll be able to parse JSON easier a lot.
Here's a classical example:
Alamofire.request("http://example.net", method: .get).responseJSON { response in
switch response.result {
case .success(let value):
let json = JSON(value)
print("JSON: \(json)")
case .failure(let error):
print(error)
}
}
If you need to pass parameters, or headers, just add it in the request method.
let headers: HTTPHeaders = [
"Content-Type:": "application/json"
]
let parameters: [String: Any] = [
"key": "value"
]
So your request will be something like this (this is POST request):
Alamofire.request("http://example.net", method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseJSON { response in
switch response.result {
case .success(let value):
print(value)
case .failure(let error):
print(error)
}
}
I haven't tested it, but it should work. Also, you need to set allow arbitary load to yes (App Transport Security Settings in info.plist) if you want to allow requests over HTTP protocol.
This is NOT recommended, but it's fine for development.
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.
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)
}
}