Así que recientemente volví a Swift e iOS después de una pausa y me encontré con un problema con la ejecución asincrónica. Estoy usando el SDK de iOS de Giphy para ahorrarme mucho trabajo, pero su documentación es prácticamente inexistente, por lo que no estoy seguro de lo que podría estar pasando bajo el capó en su función que llama a su API.
Llamo a mi función que contiene el código siguiente desde el constructor de un objeto estático (no creo que ese sea el problema, ya que también intenté llamarlo desde un método cellForItemAt para una Vista de colección).
Mi problema es que mi función regresa y la ejecución continúa antes de que finalice la llamada API. He intentado utilizar DispatchQueue.main.async y eliminar Dispatch por completo, y DispatchGroups, en vano. Lo único que funcionó fue un semáforo, pero creo recordar haber leído que no era la mejor práctica.
Cualquier consejo sería genial, he estado atrapado en esto durante muuuuucho demasiado. Muchas gracias de antemano
GiphyCore.shared.gifByID(id) { (response, error) in
if let media = response?.data {
DispatchQueue.main.sync {
print(media)
ret = media
}
}
}
return ret
2 respuestas
Mi problema es que mi función regresa y la ejecución continúa antes de que finalice la llamada API.
Ese es el objetivo de las llamadas asincrónicas. Una llamada de red puede tomar una cantidad arbitraria de tiempo, por lo que inicia la solicitud en segundo plano y le indica cuándo finalizó.
En lugar de devolver un valor de su código, tome un parámetro de devolución de llamada y llámelo cuando sepa que la llamada Giphy ha finalizado. O use una biblioteca de promesas. O el patrón delegado.
Lo único que funcionó fue un semáforo, pero creo recordar haber leído que no era la mejor práctica.
No hagas esto. Bloqueará su IU hasta que se complete la llamada de red. Como no sabe cuánto tiempo tomará, su interfaz de usuario no responderá durante un período de tiempo desconocido. Los usuarios pensarán que su aplicación se ha bloqueado en conexiones lentas.
Simplemente puede agregar esto dentro de un método y usar un controlador de finalización y, por lo tanto, no necesita esperar la respuesta. Podrías hacerlo así:
func functionName(completion: @escaping (YOURDATATYPE) -> Void) {
GiphyCore.shared.gifByID(id) { (response, error) in
if let media = response?.data {
completion(media)
return
}
}
}
Llama a tu método así
functionName() { response in
DispatchQueue.main.async {
// UPDATE the UI here
}
}
Nuevas preguntas
ios
iOS es el sistema operativo móvil que se ejecuta en el iPhone, iPod touch y iPad de Apple. Use esta etiqueta [ios] para preguntas relacionadas con la programación en la plataforma iOS. Use las etiquetas relacionadas [Objective-C] y [Swift] para problemas específicos de esos lenguajes de programación.