Christian
Christian

Reputation: 318

Pass a delegate as a parameter for NSURLSession

I have a class named RestService which I use all over my app to perform several synchronous requests to a web service. I added a new method to this class to perform an asynchronous request which again I want to reuse all over my app. This is the code for that new method:

- (void)backgroundExecutionOfService:(NSString *)serviceName 
                      withParameters:(NSDictionary *)parameters
                              inView:(UIView *)view
                        withDelegate:(UIViewController *)delegate
{
    NSString *serviceUrl = @"http://MyWebServer/public/api/clients/5";
    NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
    sessionConfig.allowsCellularAccess          = YES;
    sessionConfig.timeoutIntervalForRequest     = 10;
    sessionConfig.timeoutIntervalForResource    = 10;
    sessionConfig.HTTPMaximumConnectionsPerHost =  1;

    NSURLSession *session;
    session = [NSURLSession sessionWithConfiguration:sessionConfig
                                            delegate:delegate
                                       delegateQueue:nil];

    NSURLSessionDownloadTask *getFileTask;
    getFileTask = [session downloadTaskWithURL:[NSURL URLWithString:serviceUrl]];
    [getFileTask resume];
}

But XCode is giving me a warning about using that parameter as a delegate (Sending UIViewController * __strong' to parameter of incompatible type 'id< NSURLSessionDelegate > _Nullable'). I made sure that the view controller I'm sending as a parameter has declared < NSURLSessionDelegate > in .h and I created the delegate methods in the ViewControllers's implementation file.

- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(nullable NSError *)error{
    NSLog(@"Became invalid with error: %@", [error localizedDescription]);
}

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
 completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * __nullable credential))completionHandler{
    NSLog(@"Received challenge");
}

- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session{
    NSLog(@"Did finish events for session: %@", session);
}

The app doesn't crash but the delegate methods are never called. The synchronous web services work as expected.

Upvotes: 0

Views: 380

Answers (1)

Eli
Eli

Reputation: 56

That happened because a UIViewController class don't conform a NSURLSessionDelegate protocol. To resolve that discrepancy just change the method's signature to this like:

- (void)backgroundExecutionOfService:(NSString *)serviceName withParameters:(NSDictionary *)parameters inView:(UIView *)view withDelegate:(id<NSURLSessionDelegate>)delegate{
//... your code
}

And "read up on the basics of delegates."

Upvotes: 1

Related Questions