Search code examples
iosswiftgrand-central-dispatch

How do I wait for an asynchronous call in Swift?


So I've recently come back to Swift & iOS after a hiatus and I've run into an issue with asynchronous execution. I'm using Giphy's iOS SDK to save myself a lot of work, but their documentation is pretty much nonexistent so I'm not sure what might be happening under the hood in their function that calls their API.

I'm calling my function containing the below code from the constructor of a static object (I don't think that's the problem as I've also tried calling it from a cellForItemAt method for a Collection View).

My issue is that my function is returning and execution continues before the API call is finished. I've tried utilizing DispatchQueue.main.async and removing Dispatch entirely, and DispatchGroups, to no avail. The one thing that worked was a semaphore, but I think I remember reading that it wasn't best practice?

Any tips would be great, I've been stuck on this for waaaaaay too long. Thanks so much in advance

GiphyCore.shared.gifByID(id) { (response, error) in
        if let media = response?.data {
            DispatchQueue.main.sync {
                print(media)
                ret = media
            }
        }
    }

return ret

Solution

  • My issue is that my function is returning and execution continues before the API call is finished.

    That's the whole point of asynchronous calls. A network call can take an arbitrary amount of time, so it kicks off the request in the background and tells you when it's finished.

    Instead of returning a value from your code, take a callback parameter and call it when you know the Giphy call has finished. Or use a promise library. Or the delegate pattern.

    The one thing that worked was a semaphore, but I think I remember reading that it wasn't best practice?

    Don't do this. It will block your UI until the network call completes. Since you don't know how long that will take, your UI will be unresponsive for an unknown amount of time. Users will think your app has crashed on slow connections.