Measuring total response time for NSURLSession's dataTaskWithRequest

1k views Asked by At

When using NSURLSession's dataTaskWithRequest how can total response time be measured in the event that many NSURLSessionDataTask are created and will not necessarily be executed immediately? Storing a starting time and calculating the difference within the block doesn't account for time that a task may have been waiting for an available thread. IE:

let startTime = NSDate();
let task = session.dataTaskWithRequest(request) { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
    let responseTime = NSDate().timeIntervalSinceDate(startTime);
}
1

There are 1 answers

0
dgatwood On

I think you can probably do this with a fairly trivial custom NSURLProtocol.

  1. In your canInitWithRequest: method, call the setProperty:forKey:inRequest: method on NSURLProtocol to set a custom start time key for the request. Then reject the request (by returning NO) and allow the normal HTTP protocol to handle the request normally.

  2. When you get a response, call property:forKey:inRequest: to get the start time.

With that said, there's no guarantee that the request really will start immediately after the call to canInitWithRequest:, and because there's no good way to subclass the original HTTP protocol handler class (to wrap the startLoading method), this may or may not be precise enough. I'm not sure.

So if that doesn't work, then to improve the accuracy, you would have to create a full-blown protocol that:

  • Returns YES in canInitWithRequest: (except if the start time has already been set for that request)
  • Creates a new URL session in its startLoading method (to ensure that the request will start instantly)
  • Adds the start time to the request
  • Begins the request in that new session

But even that will not necessarily give you precise timing if the request is happening while the app is in the background or if the discretionary flag is set on the session configuration. That approach also won't work very easily if you're using more than one session with different configurations. It is, however, probably the best you can do in terms of accuracy, because I doubt that there's any way to swizzle the built-in HTTP protocol class (if such a class even exists).