URLSession Background task is not working in the background mode

The Download is not Working in the background mode even if i entitled all the necessary permission for the application it only works when the app is connected to xcode due to xcode keep the session alive but if try after removing the connection from the xcode the app not able to keep the download after 45 sec what may be the reason

my code

  var request = URLRequest(url: url)
        request.httpMethod = "GET"
        let bearerToken = SyncManager.accessToken
        request.setValue("Bearer \(bearerToken)", forHTTPHeaderField: "Authorization")
        let uniqueIdentifier = "\(self.vdmsId)_\(UUID().uuidString)"
        backgroundTaskID = UIApplication.shared.beginBackgroundTask { [weak self] in
            if let taskID = self?.backgroundTaskID {
                UIApplication.shared.endBackgroundTask(taskID)
                self?.backgroundTaskID = .invalid
            }
        }

        let CursessionConfig = URLSessionConfiguration.background(withIdentifier: uniqueIdentifier)

        CursessionConfig.isDiscretionary = false
        CursessionConfig.sessionSendsLaunchEvents = true
        CursessionConfig.shouldUseExtendedBackgroundIdleMode = true
           // Set timeout intervals
        CursessionConfig.timeoutIntervalForResource = 24 * 60 * 60 // 24 hours
        CursessionConfig.timeoutIntervalForRequest = 60 * 60 // 1 hour
        let Cursession = URLSession(configuration: CursessionConfig, delegate: self, delegateQueue: nil)

        self.CurInstanceSession  = Cursession

        self.session = Cursession
        if  SyncManager.activeSessions == nil {
            SyncManager.activeSessions = [URLSession]()
        }
        SyncManager.activeSessions?.append(Cursession)
        self.downloadCompletionHandler = completion
        let CurdownloadTask = Cursession.downloadTask(with: request)
        CurdownloadTask.resume()
 

is there any solutions and i have entitled all the neccessary permisssions like background fetch, process and i also tries with the UIApplication.shared.beginBackgroundTask but after 45 sec it gets terminated all of the suden what may be the issue

Answered by DTS Engineer in 823418022

Let me start by explaining what's going on here:

it only works when the app is connected to xcode due to xcode keep the session alive

To allow the debugger to function Xcode disable app suspension, allowing your app to run in the background indefinitely. As you're experiencing, this will heavily distort the behavior of many of our background APIs, so background app testing needs to be done without Xcode being involved.

That leads to here:

but if try after removing the connection from the xcode the app not able to keep the download after 45 sec what may be the reason

Yes, this is basically what I'd expect to happen. What the background URL session actually does is transfer your connection configuration information to nsurlsessiond so that nsurlsesiond can perform the actual transfer, NOT your app. As part of that process, the system also tries to perform that work when it unlikely to disrupt the user. That's what happened above- the transfer stayed active while your app was awake but stopped it shortly after your app suspended to minimize any user disruption. It will that resume the transfer "later" when the risk of user disruption is minimal.

Lastly, keep in mind that force quitting the app will also stop background transfer, as the force quit indicates that the user doesn't want your app to run. When I'm specifically trying to test how one of our background APIs behave, the flow I use is this:

  1. Install and run the app through Xcode.

  2. Stop the app through Xcode.

  3. Swipe up force quit/remove the app from the app switcher.

  4. Launch the app again and perform any configuration or setup work.

  5. Background the app.

Every step of that flow isn't necessarily required, but it's the safest flow that ensure you're closely replicating what a user run would look like and that Xcode isn't going to disrupt anything.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Let me start by explaining what's going on here:

it only works when the app is connected to xcode due to xcode keep the session alive

To allow the debugger to function Xcode disable app suspension, allowing your app to run in the background indefinitely. As you're experiencing, this will heavily distort the behavior of many of our background APIs, so background app testing needs to be done without Xcode being involved.

That leads to here:

but if try after removing the connection from the xcode the app not able to keep the download after 45 sec what may be the reason

Yes, this is basically what I'd expect to happen. What the background URL session actually does is transfer your connection configuration information to nsurlsessiond so that nsurlsesiond can perform the actual transfer, NOT your app. As part of that process, the system also tries to perform that work when it unlikely to disrupt the user. That's what happened above- the transfer stayed active while your app was awake but stopped it shortly after your app suspended to minimize any user disruption. It will that resume the transfer "later" when the risk of user disruption is minimal.

Lastly, keep in mind that force quitting the app will also stop background transfer, as the force quit indicates that the user doesn't want your app to run. When I'm specifically trying to test how one of our background APIs behave, the flow I use is this:

  1. Install and run the app through Xcode.

  2. Stop the app through Xcode.

  3. Swipe up force quit/remove the app from the app switcher.

  4. Launch the app again and perform any configuration or setup work.

  5. Background the app.

Every step of that flow isn't necessarily required, but it's the safest flow that ensure you're closely replicating what a user run would look like and that Xcode isn't going to disrupt anything.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Maybe the file is still downloading in the background by nsurlsessiond, but how can I track the download progress in my app once it goes to the background and later comes back to the foreground? My app shows an error banner when the download stops, but this happens every time after the app goes to the background. I assume this is because the download is no longer happening in the app itself. What should I do? and when it comes to the error part i am doing session.invalidateandcancel to keep the session fresh for the next download task will this effect the background task by the nsurlsessiond

Maybe the file is still downloading in the background by nsurlsessiond, but

That's the first point here. In most case, it ISN'T being downloaded in the background. nsurlsessiond will actually stop the download and resume it at some "later" (often hours later) point in time. This all happens while your app is suspended (assuming it's even running at all) and unaware of what is happening.

how can I track the download progress in my app once it goes to the background and later comes back to the foreground?

The article "Downloading files in the background" has an in depth rundown of how this works, but the short summary is that you'd retrieve your current task state and "jump" your progress forward to the downloads current state.

My app shows an error banner when the download stops, but this happens every time after the app goes to the background. I assume this is because the download is no longer happening in the app itself. What should I do?

Something is wrong with how your app is managing it's download tasks. See the article above for more info.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

URLSession Background task is not working in the background mode
 
 
Q