9

I am trying to download a number of files using NSURL background session with nsurlsessiontask. Everything works like charm when the app is running in debugging mode (when the device is connected to Xcode), doesn't work when unplugging device (iPad) from Xcode.

I am using Xcode 7.3.1 with iOS 9.3.5.I have already spent weeks tracing this strange behavior but haven't got any breakthroughs. May be I missing something to implement background download. Recently upgraded Xcode to 8.1.2 and iOS to 10.2.1 assuming upgradation might solve the issue but it is not.

arunjos007
  • 4,105
  • 1
  • 28
  • 43
gagan sharma
  • 256
  • 1
  • 4
  • 18
  • 6
    update your question with your code so easily find some bug or any type of error that you face – Himanshu Moradiya Feb 13 '17 at 10:48
  • 2
    Add your code that help to understand what you are doing wrong? – Mukesh Lokare Feb 13 '17 at 10:50
  • 2
    You should use NSURLSessionDownloadTask and not NSURLSessionTask to download files. And pls show code. Otherwise it is only a guessing game that will never end. – GeneCode Mar 20 '17 at 08:34
  • @GeneCode I used NSURLSessionDownloadTask only. The stranger part is whatever code I have written, my app download multiple files in background but only when it is connected to Xcode i.e when run form Xcode. My code is scattered in different files so bit difficult to share, I will try sharing code of some main files. – gagan sharma Mar 21 '17 at 06:31
  • 2
    if you not share your code than how to we solve your problem. – Sunil Prajapati Mar 23 '17 at 04:53

5 Answers5

1

refer below link and follow steps

https://www.appcoda.com/background-transfer-service-ios7/

  -(void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session{
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;

// Check if all download tasks have been finished.
[self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
    if ([downloadTasks count] == 0) {
        if (appDelegate.backgroundTransferCompletionHandler != nil) {
            // Copy locally the completion handler.
            void(^completionHandler)() = appDelegate.backgroundTransferCompletionHandler;

            // Make nil the backgroundTransferCompletionHandler.
            appDelegate.backgroundTransferCompletionHandler = nil;

            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                // Call the completion handler to tell the system that there are no other background transfers.
                completionHandler();

                // Show a local notification when all downloads are over.
                UILocalNotification *localNotification = [[UILocalNotification alloc] init];
                localNotification.alertBody = @"All files have been downloaded!";
                [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
            }];
        }
    }
}];

}

Sagar Rathode
  • 243
  • 1
  • 15
  • A link to a solution is welcome, but please ensure your answer is useful without it: [add context around the link](//meta.stackexchange.com/a/8259) so your fellow users will have some idea what it is and why it’s there, then quote the most relevant part of the page you're linking to in case the target page is unavailable. [Answers that are little more than a link may be deleted.](//stackoverflow.com/help/deleted-answers) – FelixSFD Mar 25 '17 at 10:32
0

Checkout my working code,

NSURL *url = [NSURL URLWithString:imageURL];
NSURLSessionTask *_imageDownloadTask = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    if (data) {
           //Here you can read your files from data
        if (image) {
            dispatch_async(dispatch_get_main_queue(), ^{
                  //Save your files here for cache purpose
                @try {
                    //You can handle onDownloadFinishWithFile: here too using delegate protocol 
                }
                @catch (NSException *exception) {
                          NSLog(@"%@", exception.reason);
                }
                @finally {
                  // Defines a block of related code that is subsequently executed whether an exception is thrown or not.
                }
            });
        }
    }
}];
[_imageDownloadTask resume]; 

[Note: I am using above code to download images].

Mukesh Lokare
  • 2,159
  • 26
  • 38
0

Check other parts of your code for background tasks (background tasks are started by something like this (UIApplication.beginBackgroundTask (expirationHandler: {...})).

I have run into a situation where a background tasks was created from the applicationDidEnterBackground event: the background task failed to call the completion callback UIApplication.endBackgroundTask(...), and the resulting behavior was the same as the symptoms you describe: the background download failed when the app was not connected to Xcode.`

(This is with XCode11.3, iOS13.3)

Hugo
  • 974
  • 9
  • 21
-1

In the Project Navigator, select the project target at the top side. Next, in the main window click on the Capabilities tab, and all the features that you can enable or disable simply using a switch button will be displayed there. Among them, locate the Background Modes area (second from the end), and click on the switch button at its right to enable it.enter image description here

After then swith 'Background fetch'.

enter image description here

Sargis
  • 1,196
  • 1
  • 18
  • 31
-4

Make sure the Background fetch under the background modes in capabilities is checked. enter image description here

Nishant Bhindi
  • 2,242
  • 8
  • 21