Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSURLSessionDataTask timeout subsequent requests failing

I am creating a NSMutableRequest:

self.req = [NSMutableURLRequest requestWithURL:myURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0];

The timeout is set to be 10 seconds because I don't want the user to wait too long to get a feedback. After that I create a NSURLSessionDataTask:

NSURLSessionDataTask *task = [self.session dataTaskWithRequest:self.req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    NSHTTPURLResponse * httpResp = (NSHTTPURLResponse *)response;
    if (error) {
        // this is where I get the timeout
    } 
    else if (httpResp.statusCode < 200 || httpResp.statusCode >= 300) {
        // handling error and giving feedback
    } 
    else {
        NSError *serializationError = nil;
        NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&serializationError];
    }
    [task resume];
}

The problem is the server goes into Gateway Timeout and it takes a lot of time. I get the timeout error and I give a feedback to the user, but all the following API calls fail in the same way due to timeout error. The only way to stop it is to kill the app and start over. Is there something I should do to kill the task or the connection after a timeout error? If I don't set a timeout and I wait until I receive the error code from the server all the following calls work perfectly (But the user waits a lot!).

I tried to cancel the task:

NSURLSessionDataTask *task = [self.session dataTaskWithRequest:self.req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    NSHTTPURLResponse * httpResp = (NSHTTPURLResponse *)response;
    if (error) {
        // this is where I get the timeout
        [task cancel];
    } 
    ...
    [task resume];
}
like image 875
nicky_1525 Avatar asked Jul 15 '15 10:07

nicky_1525


1 Answers

I didnt see you resume the task you started. You need to declare:

[task resume];

This line Resumes the task, if it is suspended.

Try to call the NSURLSession as follows:

[NSURLSession sharedSessison] instead of self.session

and invalidate the session by:

 [[NSURLSession sharedSession]invalidateAndCancel];

From Apple's Documentation:

When your app no longer needs a session, invalidate it by calling either invalidateAndCancel (to cancel outstanding tasks) or finishTasksAndInvalidate (to allow outstanding tasks to finish before invalidating the object).

    - (void)invalidateAndCancel

Once invalidated, references to the delegate and callback objects are broken. Session objects cannot be reused.

To allow outstanding tasks to run until completion, call finishTasksAndInvalidate instead.

  - (void)finishTasksAndInvalidate

This method returns immediately without waiting for tasks to finish. Once a session is invalidated, new tasks cannot be created in the session, but existing tasks continue until completion. After the last task finishes and the session makes the last delegate call, references to the delegate and callback objects are broken. Session objects cannot be reused.

To cancel all outstanding tasks, call invalidateAndCancel instead.

like image 182
Teja Nandamuri Avatar answered Sep 30 '22 17:09

Teja Nandamuri