Search code examples
swiftalamofire

Swift closure with Alamofire


I am making API calls to a server. I am leveraging Alamofire to handle this. I'm trying to create a function that uses Alamofire's GET function to return an object based on a custom class that holds the various outputs provided by this GET function.

It's not clear to me the way in which to do this.

Here's my custom class that will hold details about the response:

import Foundation

class ResponsePackage {

    var success = false
    var response: AnyObject? = nil
    var error: NSError? = nil

}

In another class I have the following function:

func get(apiEndPoint: NSString) -> ResponsePackage {

    let responsePackage = ResponsePackage()

        Alamofire
            .request(.GET, apiEndPoint)
            .responseJSON {(request, response, JSON, error) in
                responsePackage.response = JSON
                responsePackage.success = true
                responsePackage.error = error
        }

    return responsePackage

}

This returns nil as the call to the server is not complete before the return gets executed. I know that I should be able to do this with closures, but I am not sure how to construct this.


Solution

  • The code between the {} is the equivalent of block in objective-C : this is a chunk of code that gets executed asynchronously.

    The error you made is where you put your return statement : when you launch your request, the code in {} is not executed until the framework received a response, so when the return statement is reached, chances are, there is still no response. You could simply move the line :

    return responsePackage
    

    inside the closure, so the func return only when it has received a response. This is a simple way, but it's not really optimal : your code will get stuck at waiting for the answers. The best way you can do this is by using closure, too. This would look something like :

       func get(apiEndPoint: NSString, completion: (response: ResponsePackage) -> ()) -> Bool {
    
            let responsePackage = ResponsePackage()
            Alamofire
                .request(.GET, apiEndPoint)
                .responseJSON {(request, response, JSON, error) in
                    responsePackage.response = JSON
                    responsePackage.success = true
                    responsePackage.error = error
    
                    completion(response: responsePackage)
            }
        }