Swift Alamofire Return Value Is Empty

swift alamofire return value is empty

Here is a question that asks basically the same thing you are.

AlamoFire GET api request not working as expected

So basically what is happening is that your post request is being called in a background queue. So think of it as calling your post then continuing on to the next line. So since it is in a background thread it doesn't set the variable till after your function returns.

You could use a completion handler as explained in detail in the link I provided. Another solution would be to use NSNotificationCenter. Set up an observer and then post a notification inside your POST request.

So for example:
First declare your notification name at the top of the class where you will have your post response function as so. So that other classes can access it

let YOUR_NOTIFICATION_NAME = "NOTIFICATION NAME"
class YOUR_CLASS{

then inside the class write the code you want to execute once the POST is done.

func YOUR_FUNCTION{
...
}

Then before you execute your POST request you want to add an observer.

NSNotificationCenter.defaultCenter().addObserver(self, selector: "YOUR_FUNCTION", name: YOUR_NOTIFICATION_NAME, object: nil)

Then post your notification inside your POST request.

Alamofire.request(.POST, "XXXXXX.php", parameters: parameters)
.responseJSON { (request, response, json, error) -> Void in
...<your code>...
self.players.append(p)
NSNotificationCenter.defaultCenter().postNotificationName(YOUR_NOTIFICATION_NAME, object: self)
}

How to handle empty response using Alamofire and Combine?

This error occurs when your backend returns no data but does not return an appropriate HTTP response code (204 or 205). If this is expected behavior for your backend, you can add your response code to the list of acceptable empty response codes when you set up the publisher: .publishDecodable(T.self, emptyResponseCodes: [200]. This also requires T to either conform to Alamofire's EmptyResponse protocol, or for you to expect Alamofire's Empty type as the response.

Getting null value from API response with Alamofire

Remove the entire CodingKeys enum in Movie.

The convertFromSnakeCase strategy does already the key mapping.

And don't declare all properties carelessly as optional. Serious services like themoviedb send very consistent data. At least most likely a movie has always a title and an identifier.

How to return value from Alamofire

As mattt points out, Alamofire is returning data asynchronously via a “completion handler” pattern, so you must do the same. You cannot just return the value immediately, but you instead want to change your method to not return anything, but instead use a completion handler closure pattern.

Nowadays, that might look like:

func getOrders(completionHandler: @escaping (Result<[String: Any]>) -> Void) {
performRequest("orders", completion: completionHandler)
}

func performRequest(_ section: String, completion: @escaping (Result<[String: Any]>) -> Void) {
let url = baseURL.appendingPathComponent(section)
let params = ["consumer_key": "key", "consumer_secret": "secret"]

Alamofire.request(url, parameters: params)
.authenticate(user: consumerKey, password: consumerSecret)
.responseJSON { response in
switch response.result {
case .success(let value as [String: Any]):
completion(.success(value))

case .failure(let error):
completion(.failure(error))

default:
fatalError("received non-dictionary JSON response")
}
}
}

Then, when you want to call it, you use this completion closure parameter (in trailing closure, if you want):

api.getOrders { result in
switch result {
case .failure(let error):
print(error)

case .success(let value):
// use `value` here
}
}

// but don't try to use the `error` or `value`, as the above closure
// has not yet been called
//

Alamofire empty array

It's better to use Codable interface in Swift. Also here is nice description how use that one for Arrays.

Example:

struct Movies: Codable {

var name : String?
var description : String?
var actors : [String]?

enum CodingKeys: String, CodingKey {
case name = "name"
case description = "description"
case actors = "actors"
}

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.name = try response.decode(Bool.self, forKey: .name)
self.description = try response.decode(String.self, forKey: .description)
self.actors = try response.decode([String].self, forKey: .actors)
}

func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try response.encode(self.name, forKey: .name)
try response.encode(self.description, forKey: .description)
try response.encode(self.actors, forKey: .actors)
}
}

How to check if the API return nothing with Alamofire?

The response (as you shared) in fail-type case is:

[Response]:
[Status Code]: 200
[Headers]:
Connection: Keep-Alive
Content-Length: 0
Content-Type: text/html; charset=UTF-8
Date: Thu, 22 Apr 2021 06:54:43 GMT
Keep-Alive: timeout=5, max=100
Server: Apache/2.4.25 (Debian)
[Body]: None
[Network Duration]: 0.8882529735565186s
[Serialization Duration]: 0.0s
[Result]: success(nil)

Shows [Result]: success(nil) which means the response.data is literally nil.

I propose the following solution:

Alamofire
.request("http://172.16.5.56:8081/User/InsertNewUser")
.response { (response) in
if let data = response.data,
let string = String(data: data, encoding: .utf8) {
if string == "Email address already exist" {
self.haptics.notificationOccurred(.error)
self.activeAlert = .first
self.showAlert = true
}
//else if ... {
//handle other cases
//}
} else {
self.haptics.notificationOccurred(.success)
self.activeAlert = .second
self.showAlert = true
}
}

NOTE: I would advise against direct string comparisons unless unavoidable.

Atleast agree on a common response template and ensure the responses are not prone to typos or silly mistakes.

alamofire get request return null value

This is happening because alamofire loads the data asynchronously and before you append anything in zD.detail.append(p).
Add a completion handler for the program to wait till the loading is complete.

//here you call authenticateUser with a closure that prints responseObject
API().authenticateUser{ (responseObject, error) in
println(responseObject)
}

Then:

//authenticateUser receives your closure as a parameter
func authenticateUser(completionHandler: (responseObject: String?, error: NSError?) -> ()) {
//it passes your closure to makeAuthenticateUserCall
makeAuthenticateUserCall(completionHandler)
}

//makeAuthenticateUserCall receives your closure
func makeAuthenticateUserCall(completionHandler: (responseObject: String?,
error: NSError?) -> ()) {
Alamofire.request(.GET, loginUrlString)
.authenticate(user: "a", password: "b")
//here you pass a new closure to the responseString method
.responseString { request, response, responseString, responseError in
//in this closure body you call your completionHandler closure with the
//parameters passed by responseString and your code gets executed
//(that in your case just prints the responseObject)
completionHandler(responseObject: responseString as String!, error: responseError)
}
}

For more information read the documentation: Swift Closures

Getting null response using Alamofire

Try to pass the JSON string object of your contact array into your API params.

let arrOfUserList : [[String : AnyObject]] = [
["firstName":"Kate" as AnyObject,"lastName":"Bell" as AnyObject,"email":"katebell@mac.com" as AnyObject],
["firstName":"Daniel" as AnyObject,"lastName":"Higgins" as AnyObject,"email":"dhiggins@mac.com" as AnyObject]
]

do {
let data = try JSONSerialization.data(withJSONObject: arrOfUserList, options: [])
let jsonString = NSString(data: data, encoding: String.Encoding.utf8.rawValue)

if jsonString != nil {

let paramsContact = [Keys.vUserList : jsonString]

//Do your API calling code here
}
} catch {
print(error.localizedDescription)
}

Hope it will work for you.



Related Topics



Leave a reply



Submit