3

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.

Shizam
  • 9,507
  • 8
  • 47
  • 81

3 Answers3

4

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, */
}
bllakjakk
  • 4,965
  • 1
  • 15
  • 26
  • 1
    Those are all great ways to determine when its done/redirecting/etc but none of them indicate when the request is initially made. – Shizam Oct 01 '14 at 16:35
  • 1
    Thats closer but that would assume that when you call `resume` the request is made immediately which isn't always the case, `resume` just indicates that the task should be allowed to run. – Shizam Oct 01 '14 at 19:12
  • If accuracy is desired. You can use option02: I added sample code. – bllakjakk Oct 02 '14 at 02:34
  • 1
    I also arrived at the KVO option, it works perfectly, I came back here to add my own answer but you beat me to it :) – Shizam Oct 13 '14 at 16:56
1

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.

Brian F Leighty
  • 862
  • 10
  • 21
0

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.

Community
  • 1
  • 1
Rob
  • 371,891
  • 67
  • 713
  • 902
  • 1
    Yea #1 won't work because I'm interested in the latency, #2 looks attractive but I think you're right that it'll be cumbersome, I'm trying KVO on the `NSURLSessionTaskState` property and so far its looking like a good solution. – Shizam Oct 01 '14 at 19:14