I use NSURLSessionTask
s 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:
If you want, you could implement the delegate based rendition of
NSURLSession
and then capture the elapsed time betweendidReceiveResponse
anddidCompleteWithError
. 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.The other approach is to wrap the
NSURLSessionTask
objects in aNSOperation
subclass, just like you did withNSURLConnection
. This is trivial in the case where you are using the completion block rendition of theNSURLSessionTask
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.