es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Descarga AlamoFire con el controlador de finalización del progreso a async/await.

He creado un controlador de descarga que utiliza los manejaners de descargaProgress y respuesta completada, pero quiero convertir esto a la nueva sintaxis async/await de Swift 5.5, ya que AlamoFire lanzó una versión que soporta concurrencia en Swift.

Aquí está mi código actual usando los manejadores de respuesta completada.

func startDownload() {
    let destination = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory)

    AF.download("https://speed.hetzner.de/1GB.bin", to: destination)
        .downloadProgress { progress in
            print(progress.fractionCompleted)
        }
        .response { response in
            print(response)
        }
}

Aquí está mi intento de convertirlo a la sintaxis async-await, pero no estoy seguro de cómo implementar downloadProgress.

func startDownload() async {
    let destination = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory)

    let downloadTask = AF.download("https://speed.hetzner.de/1GB.bin", to: destination).serializingDownloadedFileURL()

    do {
        let fileUrl = try await downloadTask.value

        print(fileUrl)
    } catch {
        print("¡Error de descarga! \(error.localizedDescription)")
    }
}

Agradecería cualquier ayuda.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para implementar downloadProgress con la nueva sintaxis de async/await en Swift 5.5, puedes utilizar la API Task proporcionada por Swift concurrency. Aquí tienes el código modificado:

    func startDownload() async throws -> URL {
        let destination = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory)
        let downloadTask = AF.download("https://speed.hetzner.de/1GB.bin", to: destination)
    
        return try await withUnsafeThrowingContinuation { continuation in
            downloadTask.downloadProgress { progress in
                print(progress.fractionCompleted)
            }
            .response { response in
                switch response.result {
                case .success(let url):
                    continuation.resume(returning: url)
                case .failure(let error):
                    continuation.resume(throwing: error)
                }
            }
        }
    }
    

    En esta implementación, pasamos un cierre a withUnsafeThrowingContinuation, el cual nos proporciona un objeto Continuation que podemos utilizar para reanudar la continuación con un resultado o un error. Luego, pasamos este cierre como el controlador de finalización a AF.download, y reanudamos la continuación con la URL de descarga cuando la solicitud tenga éxito o con el error cuando falle. Mientras tanto, utilizamos el cierre downloadProgress para actualizar el progreso de la descarga. Puedes llamar a esta función con try await startDownload(), lo cual suspenderá el código llamante hasta que la descarga se complete o lance un error.

Comments are closed.