Fahim Parkar
Fahim Parkar

Reputation: 31635

AFNetWorking executes setCompletionBlock after 30 seconds if app is inactive

I am using AFNetworking for download of files in one of my project.

Everything is working properly for download if my app is awake.

The error occurs in below scenario.

If I comes back to app before 30 seconds, download continues.

Any idea how to solve this issue?


I tried setting timeout interval for NSURLRequest to 300, but still it execute setCompletionBlock after 30 seconds.

NSURLRequest *request = [NSURLRequest requestWithURL:
  [NSURL URLWithString:currentURL] cachePolicy:NSURLRequestUseProtocolCachePolicy 
  timeoutInterval:300];
operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation start];

Upvotes: 0

Views: 437

Answers (1)

Rob
Rob

Reputation: 437432

Two options:

  1. See the Executing a Finite-Length Task in the Background section of the iOS App Programming Guide:App States and Multitasking. Basically, before you start your network request, inform the OS that you want to request additional time to complete this network request if the app happens to go into the background:

    UIApplication *application = [UIApplication defaultApplication];
    
    bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
        // Clean up any unfinished task business by marking where you
        // stopped or ending the task outright.
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];
    

    This assumes you have some instance variable or class property for that bgTask:

    UIBackgroundTaskIdentifier bgTask;
    

    Anyway, inside the network request's completion block, end the background task:

    if (bgTask != UIBackgroundTaskInvalid) { 
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    });
    

    If you do the above, the app will be allowed to have a few minutes to complete the network request when the app enters the background. Note, if you have multiple requests running in the background, you will presumably want a separate UIBackgroundTaskIdentifier for each request.

  2. In iOS 7.0 and later, you have NSURLSession, which permits a much richer background network request mechanism. AFNetworking offers AFURLSessionManager as an interface for NSURLSession, but it's nowhere as robust as AFHTTPRequestManager.

    See the Background Transfer Considerations section of the URL Loading System Programming Guide: Using URLSession. Basically, you need to:

    • Create NSURLSessionConfiguration using backgroundSessionConfiguration: (in iOS 8, it's backgroundSessionConfigurationWithIdentifier:).

    • Issue only NSURLSessionDownloadTask or NSURLSessionUploadTask requests.

    • Use the delegate-based implementation of those NSURLSessionTask factory methods.

    • Make sure to implement handleEventsForBackgroundURLSession: in your app delegate, saving the completionHandler.

    • Implement a URLSessionDidFinishEventsForBackgroundURLSession method in your NSURLSessionDelegate object.

Upvotes: 1

Related Questions