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);
}
I think you can probably do this with a fairly trivial custom
NSURLProtocol
.In your
canInitWithRequest:
method, call thesetProperty:forKey:inRequest:
method onNSURLProtocol
to set a custom start time key for the request. Then reject the request (by returningNO
) and allow the normal HTTP protocol to handle the request normally.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 thestartLoading
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:
YES
incanInitWithRequest:
(except if the start time has already been set for that request)startLoading
method (to ensure that the request will start instantly)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).