Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Eric Gu
Eric Gu
3,871 Points

Swift JSON Asynchronous Calls

I was wondering if anyone more experienced than I can shed light on why I can print a value for convertedAmount inside the function to the log but when I try to return convertedAmount, it shows as 0.

Am I missing something?

Thank you!!!!

    func convertCurrency(#localAmount:Double, localCurrency:String, foreignCurrency: String)->Double{

        let baseURL = NSURL(string: "http://www.freecurrencyconverterapi.com/api/v2/")
        let query = String(localCurrency)+"_"+String(foreignCurrency)
        let forecastURL = NSURL(string: "convert?q="+query, relativeToURL: baseURL)
        var convertedAmount:Double = 0.0

        //use a session object to manage.//like the sun
        let sharedSession = NSURLSession.sharedSession()

        let downloadTask:NSURLSessionDownloadTask = sharedSession.downloadTaskWithURL(forecastURL, completionHandler: { (location:NSURL!, response: NSURLResponse!, error: NSError!) -> Void in

            if error == nil {
                let dataObject = NSData(contentsOfURL: location)
                let conversionDictionary:NSDictionary = NSJSONSerialization.JSONObjectWithData(dataObject, options: nil, error: nil) as NSDictionary
                if let results = conversionDictionary["results"] as? NSDictionary{
                    if let queryResults = results[query] as? NSDictionary{
                        if let exchangeRate = queryResults["val"] as? Double{
                            convertedAmount = (localAmount * exchangeRate)
                            print(convertedAmount)
                            //prints here


                        }
                    }
                }

            }
        })

        downloadTask.resume()

        //converted amount is 0 here
        return convertedAmount


    }

}

2 Answers

Stone Preston
Stone Preston
42,016 Points

my guess is that you are actually assigning the value to the convertedAmount in the background thread, and that your function is returning before that background thread finishes. try putting your return in the completion block of the background thread instead. that might work

Eric Gu
Eric Gu
3,871 Points

Thanks for your answer. Am I forced to use a synchronous call? Can I wait for the download to finish and then return?

Stone Preston
Stone Preston
42,016 Points

try moving the return into the completion closure. it might complain that it reached the end of a non void function though, you will probably just have to experiment a bit. one thing you may have to do is separate your background code into one function, and then the rest of the code into another that calls that background function. that way you can wait until the background thread completes, then return a value

Eric Gu
Eric Gu
3,871 Points

To solve this in the short-term, I had to make a synchronous call. My network query is small.