How to determine when NSURLSessionTask's reque

2019-07-21 12:09发布

问题:

I use NSURLSessionTasks and I'm trying to monitor how long some of my HTTP Requests take, what delegate method (or something else) can I monitor for when the NSURLSessionTask actually makes the initial request? If this were a NSURLConnection inside an NSOperation I'd just start a timer when I start the request but I don't have control over when tasks start.

回答1:

Please check NSURLSessionTaskDelegate. It has following delegate callbacks:

URLSession:task:didCompleteWithError:
URLSession:task:didReceiveChallenge:completionHandler:
URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:
URLSession:task:needNewBodyStream:
URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:

To calculate time interval.

Option 01 [Approximate]:

You should start a timer just after the call to resume method and and calculate when the delegate callback didCompleteWithError is invoked.

self.dataTask = [self.session dataTaskWithRequest:theRequest];
[self.dataTask resume];

NSTimeInterval totalCountdownInterval;
NSDate* startDate = [NSDate date];
NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(checkCountdown:) userInfo:nil repeats:YES];

Option 02 [If accuracy is desired]:

NSURLSessionTask’s properties are all KVO-compliant.

[self.dataTask addObserver:self forKeyPath:@"someKeyPath" options:NSKeyValueObservingOptionOld context:nil];
[self.dataTask resume];

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
  // do some calculation after checking state

   /* 
NSURLSessionTaskStateRunning = 0,                     
    NSURLSessionTaskStateSuspended = 1,
    NSURLSessionTaskStateCanceling = 2,                   
    NSURLSessionTaskStateCompleted = 3, */
}


回答2:

I know this is an old question but for those searching the delegate method func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) on URLSessionTaskDelegate should be able to provide plenty of info about the request including how long it took.



回答3:

Two options:

  1. If you want, you could implement the delegate based rendition of NSURLSession and then capture the elapsed time between didReceiveResponse and didCompleteWithError. This admittedly doesn't capture the latency involved in receiving the response, but if you're looking for a simple measure that factors out the time waiting for an available connection, that's one approach.

  2. The other approach is to wrap the NSURLSessionTask objects in a NSOperation subclass, just like you did with NSURLConnection. This is trivial in the case where you are using the completion block rendition of the NSURLSessionTask factory methods. It's a little more cumbersome when using the delegate based approach (because, infuriatingly, NSURLSession doesn't allow us to specify delegate objects for the individual tasks (even though they let us associate completion blocks for them), but rather all of the task-specific delegate methods are called at the session object level).

    Anyway, when you wrap it in a NSOperation subclass, you can capture your complete elapsed time quite easily.