2010-11-07 27 views
2

J'ai une application Cocoa Mac configurée pour télécharger des fichiers dans un dossier spécifique en utilisant NSURLDownload. Cela fonctionne très bien avec un seul téléchargement à la fois. Cependant, si j'essaie de lancer plusieurs téléchargements, tous sauf le dernier échoueront immédiatement.Simultaneous NSURLDownloads

Existe-t-il un moyen d'utiliser NSURLDownload pour plusieurs téléchargements simultanés? Ou quel serait un bon moyen de mettre en file d'attente plusieurs URL à télécharger dans l'ordre? Ou y at-il un moyen plus approprié d'accomplir ceci (NSURLConnection a semblé possible mais je ne savais pas si je pourrais définir l'emplacement de téléchargement et le nom de fichier comme je peux avec NSURLDownload)?

Répondre

-1

Si vous ciblez 10.5+, vous devriez regarder NSOperation. Il devrait vous permettre de créer une solution générique pour un seul téléchargement, puis utiliser les fonctions de file d'attente intégrées pour gérer les dépendances si vous avez besoin de certaines opérations pour terminer le téléchargement avant que les autres ne commencent. Gardez à l'esprit que ces API attendent souvent que les méthodes déléguées impliquées soient exécutées sur le thread principal. Vous devez donc vous assurer que cela se produit si vous travaillez avec des API asynchrones fonctionnant via des méthodes déléguées. (Vous pouvez le faire simplement en utilisant performSelectorOnMainThread: et friends)

2

Chaque NSURLDownload représente une seule instance de téléchargement. Vous essayez probablement de réutiliser le même plusieurs fois. C'est un système intrinsèquement asynchrone qui utilise déjà des threads d'arrière-plan. Voici un exemple basé sur le code exemple d'Apple:

- (void)startDownloadingURL:sender 
{ 
    // Create a couple requests. 
    NSURLRequest *requestOne = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.apple.com"] 
               cachePolicy:NSURLRequestUseProtocolCachePolicy 
              timeoutInterval:60.0]; 

    NSURLRequest *requestTwo = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://stackoverflow.com"] 
               cachePolicy:NSURLRequestUseProtocolCachePolicy 
              timeoutInterval:60.0]; 

    // Create two download instances 
    NSURLDownload *downloadOne = [[NSURLDownload alloc] initWithRequest:requestOne delegate:self]; 
    NSURLDownload *downloadTwo = [[NSURLDownload alloc] initWithRequest:requestTwo delegate:self]; 

    if (downloadOne) { 
     // Set the destination file. 
     [downloadOne setDestination:@"/tmp" allowOverwrite:YES]; 
    } else { 
     // inform the user that the download failed. 
    } 
    if (downloadTwo) { 
     // Set the destination file. 
     [downloadTwo setDestination:@"/tmp" allowOverwrite:YES]; 
    } else { 
     // inform the user that the download failed. 
    } 
} 


- (void)download:(NSURLDownload *)download didFailWithError:(NSError *)error 
{ 
    // Release the connection. 
    [download release]; 

    // Inform the user. 
    NSLog(@"Download failed! Error - %@ %@", 
      [error localizedDescription], 
      [[error userInfo] objectForKey:NSErrorFailingURLStringErrorKey]); 
} 

- (void)downloadDidFinish:(NSURLDownload *)download 
{ 
    NSLog(@"The download %@ has finished.", download) 

    // Release the download connection. 
    [download release]; 
} 

Si vous essayez d'utiliser le même pour les deux NSURLDownload NSURLRequests, il va tuer la connexion précédente.

+0

Salut, y at-il un moyen pour que 'downloadDidFinish' ne soit appelé que si les deux téléchargements sont terminés? Merci! – TCB13

+0

que se passe-t-il si je place le 'downloadTwo' dans' downloadDidFinish'? Puis-je faire cela et ajouter un autre 'downloadDidFinish' pour m'assurer que les fichiers achetés seront téléchargés avant que mon programme continue d'exécuter du code? Mais de cette façon, n'y a-t-il pas un risque que le second téléchargement appelle le premier 'downloadDidFinish' et se lance dans une boucle de téléchargement infinie? : S Désolé pour new Obj-C. QT est un peu plus simple ...: S – TCB13

0

Je voudrais utiliser second NSOperation si votre sur 10.5+ ou plus. Vous pouvez simplement lancer une opération sur une file d'attente pour chaque téléchargement. Ou vous pouvez simplement utiliser la requête sendSynchronous et l'utiliser avec la méthode addOperationWithBlock (10.6+) de NSOperationQUeue, puis dans votre bloc vous lancez la file d'attente que vous pouvez utiliser [[NSOperationQueue mainQueue] addOperationWithBlock:^{lorsque vous utilisez le code vous devez exécuter ou tout simplement besoin périodiquement pour rafraîchir l'interface utilisateur sur le thread principal, comme si ...

[myQueue addOperationWithBlock:^{ 
    //download stuff here... 
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 
     //update main thread UI 
    }]; 
}]; 

vous juste besoin de le faire pour chaque téléchargement.

+1

Cela ne sert à rien puisque 'NSURLDownload' est déjà asynchrone, donc pas de blocage du thread principal pour la durée du téléchargement. –