Set number of concurrent downloads with NSURLSessionDownloadTask

前端 未结 2 1219
被撕碎了的回忆
被撕碎了的回忆 2021-01-31 17:01

I\'m using the new NSURLSession API and allowing the user to download files. I\'d like to try and tell my NSURLSession how many simultaneous downloads to run, but I don\'t see a

2条回答
  •  抹茶落季
    2021-01-31 17:30

    I found a workaround for this timeouts.

    Tried to download a file with slow connection simulation on device(Settings -> Developer -> Network link conditioner -> Choose a profile -> 3G -> Enable).

    Here is my sample 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]);
        }
    }
    

    And my output:

    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!
    ...
    

    As you can see tasks started time out after 2 minutes

    I played with timeoutIntervalForResource and timeoutIntervalForRequest parameters and in case we set both to 0 it will downloads without timeouts. But I think it isn't a good idea because of battery drawn. I think that 10 minutes or something like it will be a good value for it. But you have to set both parameters to the same value.

    Apple docs:

    timeoutIntervalForRequest - The timeout interval to use when waiting for additional data. timeoutIntervalForResource - The maximum amount of time that a resource request should be allowed to take.(timeout for all tasks to one resource)

    Noticed strange thing: in case we set timeoutIntervalForResource = 60 and timeoutIntervalForRequest = 30, tasks will time out after 30 seconds! But most of them won't even start!

    Looks like timer for timeoutIntervalForRequest started when task resumed. In that case we resumed all tasks in the same time and each task's timeout has to be as a resource timeout.

    Also, I can advise wwdc13 705 session with a great demo about background session with download task.

提交回复
热议问题