tech_human
tech_human

Reputation: 7102

Passing response to controller while converting NSURLConnection to NSURLSession

I have something like service API class which implements NSURLConnectionDelegate methods. I noticed that some of the methods of this are deprecated and Apple now suggests to use NSURLSession. I created this service API's own delegate which the calling class would implement and that would be executed when a response is received. I am looking for how I can do something similar while using NSURLSession.

My present stuff with NSURLConnection:

@class ServiceAPI;
@protocol ServiceAPIDelegate <NSObject>

- (void)getResponseData:(NSData *)responseData;

@end

@interface ServiceAPI : NSObject<NSURLCoDelegate>
- (void)httpServiceRequest:(NSMutableURLRequest *)serviceRequest;
@property (nonatomic, weak) id <ServiceAPIDelegate> delegate;
@end

In ServiceAPI implementation file:

- (void)httpServiceRequest:(NSMutableURLRequest *)serviceRequest {
    //[[NSURLSession sharedSession] dataTaskWithRequest:serviceRequest] resume];
    self.requestConnection = [NSURLConnection connectionWithRequest:serviceRequest delegate:self];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    [self.delegate getResponseData:self.responseData sender:self];
}

Class making request and getting response:

@interface CallingController : UITableViewController<ServiceAPIDelegate>
@end

Implementation file CallingController:

- (void)getResponseData:(NSData *)responseData {
   // Do something with response. 
}

How do I let the calling class handle the response method just like NSURLConnection while using NSURLSession. While reading NSURLSession looks like the request and response are handled together using completion handler something like this:

NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:@"https://itunes.apple.com/search?term=apple&media=software"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
    NSLog(@"%@", json);
}]; 

I still want to have a service API class and my controller would just pass down the request to service API to make calls and once the response is back, it would be passed down to controller. How do I pass the response to the controller while using NSURLSession.

Upvotes: 0

Views: 190

Answers (2)

GeneCode
GeneCode

Reputation: 7588

Something like this:

   @class ServiceAPI;

    @protocol ServiceAPIDelegate <NSObject>

    - (void)getResponseData:(NSData *)responseData;

    @end

    @interface ServiceAPI : NSObject<NSURLSessionDelegate>
    - (void)httpServiceRequest:(NSMutableURLRequest *)serviceRequest;
    @property (nonatomic, weak) id <ServiceAPIDelegate> delegate;
    @end

In Implementation

- (void)httpServiceRequest:(NSMutableURLRequest *)serviceRequest {
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *downloadTask =

    [session dataTaskWithRequest:serviceRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

        [self.delegate getResponseData:data sender:self];

    }];

    [downloadTask resume];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    // no use
}

Upvotes: 0

The Mach System
The Mach System

Reputation: 6963

You can still achieve what you wish by initialising NSURLSessionDataTask without completion block. That way, it will call the delegate methods instead.

For example:

NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:@"https://itunes.apple.com/search?term=apple&media=software"]];
[dataTask resume];

Implement NSURLSessionDataDelegate

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
                                 didReceiveResponse:(NSURLResponse *)response
                                  completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler;

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
                                     didReceiveData:(NSData *)data;

Also implement NSURLSessionTaskDelegate to know when the request is completed.

/* Sent as the last message related to a specific task.  Error may be
 * nil, which implies that no error occurred and this task is complete. 
 */
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                           didCompleteWithError:(nullable NSError *)error;

Upvotes: 0

Related Questions