Fin de tâche.
Bonjour,
Je télécharge des images depuis un serveur. Voici un extrait de mon code
func loadImages() {
for urlImage in urlImageList() {
let serverUrl = k.imagesServerUrl.appendingPathComponent(urlImage)
let destinationUrl = k.imagesLocalUrl.appendingPathComponent(urlImage)
downloadFromServer(serverUrl: serverUrl, localDestination: destinationUrl)
}
}
// MARK: - Sync Helper Func
func downloadFromServer(serverUrl: URL, localDestination: URL) {
// Create destination URL
let destinationFileUrl = localDestination
let session = URLSession(configuration: .default)
let request = URLRequest(url:serverUrl)
let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
// Code .... }
task.resume()
}
Je l'ai un peu épuré pour en garder l'essentiel. Ma boucle lance ma fonction downloadFromServer pour toutes les images contenu dans ma liste d'url de mes images. Cela fonctionne. Mais voilà j'aimerai savoir lorsque toutes mes images ont été téléchargées. En gros quand il n'y a plus de task en cours.
Si vous avez une idée...
D'avance merci
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Tu peux utiliser un dispatch group avec un create(), avec un enter() à chaque itération de la for loop, leave() à la find de chaque téléchargement, et enfin un notify() pour indiquer que faire lorsqu'elles ont toutes été téléchargées.
Il va falloir implémenter des closures par contre dans downloadFromServer()
En pseudo code (non-testé, ni au compilo, ni au run-time, tappé ici-même, et vu que je ne suis pas dév' Swift) par rapport à ton code:
J'ai rajouté un closure à ta méthode afin de pouvoir quitter le dispatch_group_t.
Potentiellement rajouter une closure également à loadImages() afin de dire à celui qui l'appelle de faire quelque chose...
Merci larme, je regarde ça et j'envois le code testé.
Code testé, Swift 4.
Encore merci @Larme
Je relance ce sujet car j'ai des problèmes de downloads de mes images. Pas mal d'images qui ne se téléchargent pas à cause de problèmes de TimeOut : NSURLErrorDomain Code -1001 "The request timed out"
J'ai essayé avec Alamofire configuré comme cela
Au départ j'avais écris cela moi même
Les deux codes produisent le même résultat quand j'ai un accès de mauvaise qualité : pas mal de Timed Out. Quand la liaison est bonne tout va bien...
D'avance merci pour votre aide
PS1: Peut-être que ce message aurait mérité un nouveau Topic mais en le postant à la suite, cela permet aussi de grouper la problématique...
PS2: Tant qu'à faire je préfèrerais trouver une solution à partir de mon code plutôt qu'à partir d'Alamofire. Je préfère toujours mon propre code plutôt que de dépendre d'une bibliothèque issue d'un tiers.
Au pire en cas de timeout tu peux relancer simplement la requête non ? avec peut être un temps d'attente et/ou une vérification de la connectivité (avec Reacheability ou en essayant de téléchargement une ressource pour laquelle tu est sur qu'elle sera présente sans limite de temps) avant de relancer la requête et au bout de 2 ou 3 tentatives appeler le completionhandler avec false. Et si tu as trop d'échec attendre que la connectivité soit rétablie (en vérifiant régulièrement) puis relancer les téléchargements (ou pas).
Tu peux conserver les infos de téléchargement dans une structure (url, nombre d'échec, etc...) (ou une classe) pour te permettre de recréer les tâches de téléchargement.
J'éclaterai pour cela la méthode downloadFromServer en deux
1/ downloadFromServer "actuel" (appel ce createDownloadTask et tasl.resume() si la connectivité est présente)
2/ createDownloadTask qui va créer la tâche de développement avec un completionhandler "interne" qui va réagir en fonction du résultat (soit appel du vrai completionhandler, soit vérification de la connectivité, incrément du nombre d'échec, vérification du nombre d'échec total, etc...). Si le nombre d'échec est trop important, il faut stocker les infos de download demandés et les relancer lorsque la connectivité est rétablie. Il serait aussi possible de définit un temps d'attente de connectivité max au de la duquel il est certain que la connectivité ne sera jamais établie et appeler les completionhandler(false) de toute les downloads en attente...