Reputation: 3
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
Upvotes: 0
Views: 699
Reputation: 54
You could just add this inside a method and use a completion handler and therefore do you not need to wait for the response. You could do it like this:
func functionName(completion: @escaping (YOURDATATYPE) -> Void) {
GiphyCore.shared.gifByID(id) { (response, error) in
if let media = response?.data {
completion(media)
return
}
}
}
Call your method like this
functionName() { response in
DispatchQueue.main.async {
// UPDATE the UI here
}
}
Upvotes: -1
Reputation: 73936
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.
Upvotes: 3