NSURLSession delegate vs. completionHandler
If you want to add a custom delegate class, you need to implement the NSURLSessionDataDelegate
and NSURLSessionTaskDelegate
protocols at the minimum.
With the methods:
NSURLSessionDataDelegate - get continuous status of your request
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {
receivedData=nil; receivedData=[[NSMutableData alloc] init];
[receivedData setLength:0];
completionHandler(NSURLSessionResponseAllow);
}
NSURLSessionDataDelegate
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveData:(NSData *)data {
[receivedData appendData:data];
}
NSURLSessionTaskDelegate
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error {
if (error) {
// Handle error
}
else {
NSDictionary* response=(NSDictionary*)[NSJSONSerialization JSONObjectWithData:receivedData options:kNilOptions error:&tempError];
// perform operations for the NSDictionary response
}
If you want to separate the delegate code (middle layer) from your calling class (generally its good practice to have separate class/layer for network calls), the delegate of NSURLSession has to be :-
NSURLSession *session=[NSURLSession sessionWithConfiguration:sessionConfig delegate:myCustomDelegateClass delegateQueue:nil];
Ref Links:
- NSURLSession Class Reference
- iOS NSURLSession Example (HTTP GET, POST, Background Downlads )
- From NSURLConnection to NSURLSession
Related videos on Youtube
AndrewSB
Updated on February 02, 2020Comments
-
AndrewSB about 4 years
I've always used completion handlers. With
NSURLConnection
and now withNSURLSession
. It's led to my code being really untidy, especially I have request within request within request.I wanted to try using delegates in
NSURLSession
to implement something I've done untidily withNSURLConnection
.So I created a
NSURLSession
, and created adataTask
:NSURLSessionDataTask *dataTask = [overallSession dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if(error == nil) { NSString * text = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]; NSLog(@"Data = %@",text); } }]; [dataTask resume];
Right now I have a
completionHandler
for the response, how would I switch to delegates to manage the response and data? And can I add anotherdataTask
from the delegate of this one? Using the cookies that thisdataTask
created and placed into the session? -
Smart Home over 8 yearsIf multiple concurrent requests can be in flight at the same time, this approach won't work since you will append data from different tasks together. In this case, use a dictionary to append only data belonging to particular task.
-
Lazar Kukolj over 7 yearsthank you for the 2nd link! it helped a lot and was exactly what i needed!
-
dgatwood over 7 yearsYou can do all that stuff, but generally unless you're doing custom authentication, custom caching, or trying to make use of the data before you receive all of it (e.g. partial parsing of a web page to start rendering sooner), it is usually cleaner to use callbacks and hand off the resulting data to a method if things get too deeply nested and confusing. Just my $0.02.
-
Nikita about 6 yearsin case the delegate callbacks are configured to return on main queue, the [receivedData appendData:data]; can be an expensive operation, so it should be moved to global queue in an async way and there should be added a lock;