2

I have a function that download data using Alamofire and then I would like to return that data. Now I know that Alamofire runs asynchronously and in order to to return data I should use completionHandler, however I don't get it how to use it. Since I am not the first with such problem, I found some solutions to similar problems, yet I am not sure to apply them to my case. Here is my code:

func downloadImageFromServer(imageUrl: String) -> (String, String) {
    var myData1 = String()
    var myData2 = String()
    Alamofire.request(.GET, imageUrl)
        .responseImage { response in
            switch response.result {
            case .Success:
                if let newImage = response.result.value {
                myData1 = //returned image name
                myData2 = //edited image name
                }
            case .Failure:
                //Do something
            }
    }
    return (myData1, myData2)
}

Should I do something like this:

func downloadImageFromServer(imageUrl: String, completionHandler: (String?, String?) -> ()) {
    var myData1 = String()
    var myData2 = String()

    Alamofire.request(.GET, imageUrl)
        .responseImage { response in
            switch response.result {
                //if user does have a photo
            case .Success:
                myData1 = //Something
                myData2 = //Something else
                completionHandler(myData1 as? String, myData2 as? String)
            case .Failure:
                //Print error
            }
    }
}

Update Yes, my question is very similar to that other question, however in my case, code has to return 2 values and that's where I find difficulties. Here's my code for gettin values:

 func getImages(orders: String, completionHandler: (String?, String?) -> ()) {
    justDoIt(orders, completionHandler: completionHandler)
}

and then

getImages(imgURL) { responseObject, error in
    print(responseObject)
    return
}

And it works, however I am able to access only first value of the two, how to access both?

Georgy
  • 25
  • 5
  • 2
    Yes. You could also add variable to completionHandler closure, that will indicate if it is success or error (or you could add errorHandler). – sunshinejr Dec 22 '15 at 18:52
  • 1
    Good example here: [How to return value from Alamofire](http://stackoverflow.com/questions/27390656/how-to-return-value-from-alamofire) – Eric Aya Dec 22 '15 at 18:52
  • @EricD. I've seen that example, my second code is based on that example, however I am not if it's right because I have to return 2 variables. Also since function is returning 2 variables I am not sure how to access them. Although I have an idea – Georgy Dec 22 '15 at 18:57
  • @sunshine What about getting data from that function? That seems to be hard part for me – Georgy Dec 22 '15 at 19:25

1 Answers1

2

Your approach is correct. You could use another variable in your closure to see if the request was called properly (or another variable in function, e.g. errorHandler). Example of usage:

downloadImageFromServer(imgURL) { (data1, data2) in
    print("Data1: \(data1). Data2: \(data2)")
}

Basic example of adding success/failure variable to your function:

func downloadImageFromServer(imageUrl: String, completionHandler: (Bool, String?, String?) -> ()) {
    var myData1 = String()
    var myData2 = String()

    Alamofire.request(.GET, imageUrl)
        .responseImage { response in
            switch response.result {
                //if user does have a photo
            case .Success:
                myData1 = //Something
                myData2 = //Something else
                completionHandler(true, myData1 as? String, myData2 as? String)
            case .Failure:
                completionHandler(false, nil, nil)
                //Print error
            }
    }
}

Usage of the improved version of downloadImageFromServer():

downloadImageFromServer(imgURL) { (succes, data1, data2) in
    if success {
        print("Success. Data1: \(data1). Data2: \(data2)")
    } else {
        print("Error. Data1: \(data1). Data2: \(data2)")
    }
}
sunshinejr
  • 4,834
  • 2
  • 22
  • 32
  • I was wondering if you can use completion handlers as above without having to give it an argument to the parameter imgURL. So that I can call the downloadImageFromServer method like so: `downloadImageFromServer()` and that that function will return me the print statement? @Georgy @Sunshinejr – Caspert Oct 27 '16 at 14:06