Définir le nombre de téléchargements concurrents avec NSURLSessionDownloadTask

j'utilise la nouvelle API NSURLSession et j'autorise l'utilisateur à télécharger des fichiers. J'aimerais essayer de dire à ma NSURLSession combien de téléchargements simultanés il faut faire, mais je ne vois pas comment le faire. Je voudrais essayer d'éviter de gérer les tâches de téléchargement moi - même, serait beaucoup mieux si je pouvais dire au système combien de permettre à la place-ce serait mieux pour faire la queue des téléchargements d'arrière-plan aussi bien quand mon application n'est pas en cours d'exécution. Est-il un moyen de faire cela?

25
demandé sur Cory Imdieke 2014-01-02 21:58:14
la source

2 ответов

Vous pouvez le mettre dans le NSURLSessionConfiguration objet HTTPMaximumConnectionsPerHost propriété.

19
répondu CouchDeveloper 2014-01-02 22:05:13
la source

j'ai trouvé une solution de contournement pour ces temps morts.

essayé de télécharger un fichier avec simulation de connexion lente sur l'appareil(Paramètres -> développeur -> conditionneur de lien réseau -> choisir un profil -> 3G -> activer).

Voici mon exemple de code:

- (void) methodForNSURLSession{
  NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
  _tasksArray = [[NSMutableArray alloc] init];
  sessionConfig.HTTPMaximumConnectionsPerHost = 3;
  sessionConfig.timeoutIntervalForResource = 120;
  sessionConfig.timeoutIntervalForRequest = 120;
  NSURLSession* session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];

  // data tasks
  [self createDownloadTasksWithSession:session];

}

- (void) createDownloadTasksWithSession:(NSURLSession *)session{
  for (int i = 0; i < 100; i++) {
    NSURLSessionDownloadTask *sessionDownloadTask = [session downloadTaskWithURL: [NSURL URLWithString:@"https://discussions.apple.com/servlet/JiveServlet/showImage/2-20930244-204399/iPhone%2B5%2BProblem2.jpg"]];
    [_tasksArray addObject:sessionDownloadTask];
    [sessionDownloadTask addObserver:self forKeyPath:@"countOfBytesReceived" options:NSKeyValueObservingOptionOld context:nil];
    [sessionDownloadTask resume];
  }
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
  if([[change objectForKey:@"old"] integerValue] == 0){
    NSLog(@"task %d: started", [_tasksArray indexOfObject: object]);
  }
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
    if (!error) {
      NSLog(@"task %d: finished!", [_tasksArray indexOfObject:task]);
    } else if (error.code == NSURLErrorTimedOut) {
      NSLog(@"task %d: timed out!", [_tasksArray indexOfObject:task]);
    }
}

et ma sortie:

2014-01-10 10:38:48.769 TestApplication[2442:1803] task 1: started
2014-01-10 10:38:49.517 TestApplication[2442:1803] task 2: started
2014-01-10 10:38:50.273 TestApplication[2442:4b03] task 0: started
2014-01-10 10:40:11.794 TestApplication[2442:5003] task 2: finished!
2014-01-10 10:40:13.924 TestApplication[2442:1803] task 3: started
2014-01-10 10:40:26.221 TestApplication[2442:1d0f] task 1: finished!
2014-01-10 10:40:28.487 TestApplication[2442:1d0f] task 4: started
2014-01-10 10:40:43.007 TestApplication[2442:440f] task 5: timed out!
2014-01-10 10:40:43.009 TestApplication[2442:440f] task 6: timed out!
2014-01-10 10:40:43.011 TestApplication[2442:440f] task 7: timed out!
...

comme vous pouvez le voir les tâches commencées chronométrent après 2 minutes

j'ai joué avec timeoutIntervalForResource et timeoutIntervalForRequest paramètres et dans le cas où nous définissons les deux à 0 Il se télécharge sans temps mort. Mais je pense que ce n'est pas une bonne idée car la batterie dessinée. Je pense que 10 minutes ou quelque chose comme ça sera une bonne valeur pour elle. Mais vous devez définir les deux paramètres à la même valeur.

Apple docs:

timeoutIntervalForRequest - l'intervalle de temps à utiliser en attente pour des données supplémentaires. timeoutIntervalForResource - Le montant maximum de temps qu'une demande de ressource devrait être autorisé à prendre.(le délai pour toutes les tâches d'un de ressources)

a remarqué une chose étrange: au cas où nous mettions timeoutIntervalForResource = 60 et timeoutIntervalForRequest = 30, les tâches au bout de 30 secondes! Mais la plupart d'entre eux ne vont même pas commencer!

Ressemble minuterie pour l' timeoutIntervalForRequest commencé lorsque la tâche a repris. Dans ce cas, nous avons repris toutes les tâches dans le même temps et le temps d'arrêt de chaque tâche doit être comme un temps d'arrêt des ressources.

aussi, je peux conseiller wwdc13 705 session avec une grande démo sur la session de fond avec la tâche de téléchargement.

13
répondu kaspartus 2017-10-06 16:15:39
la source

Autres questions sur