2

I am newbie IOS programming. I want to create a sample app which allow user to download many files from my server. For example, I have 10 files, then should I call method let configuration = URLSessionConfiguration.background(withIdentifier: "firstTask") for 10 times but difference identifier like first file withIdentifier: "firstTask" and second file should be withIdentifier: "secondTask"?. The reason is that I want to able user to download same file name then I just modify withIdentifier: "" with other name. Is that right? Please give me some advices.

Other question:

How can we invalidate session with a particular identifier?

Enrique Bermúdez
  • 1,740
  • 2
  • 11
  • 25
Visal Sambo
  • 1,270
  • 1
  • 19
  • 33

2 Answers2

1

According to the documentation:

identifier The unique identifier for the configuration object. This parameter must not be nil or an empty string.

Also there is a statement:

If an iOS app is terminated by the system and relaunched, the app can use the same identifier to create a new configuration object and session and to retrieve the status of transfers that were in progress at the time of termination. This behavior applies only for normal termination of the app by the system. If the user terminates the app from the multitasking screen, the system cancels all of the session’s background transfers. In addition, the system does not automatically relaunch apps that were force quit by the user. The user must explicitly relaunch the app before transfers can begin again.

Finally:

Create a background URLSessionConfiguration object with the class method background(withIdentifier:) of URLSession, providing a session identifier that is unique within your app. Because most apps need only a few background sessions (usually one), you can use a fixed string for the identifier, rather than a dynamically generated identifier. The identifier doesn’t need to be unique globally.

So it's reasonable to use one unique identifier for your app. For example it may contain bundle id, like com.awesomeapps.appname.sessionId for the entire app.

Vladimir Kaltyrin
  • 621
  • 1
  • 4
  • 16
  • I got your point that `identifier` for my app should be unique. for example if my first task was identifier named `mySession` and it downloaded complete. If i download another file then i should use the same `identifier` right? Should i invalidate the session after downloaded complete? Then, when i want to download another file then, the new session will be created. – Visal Sambo May 29 '18 at 15:07
  • @VisalSambo If you want to download the next file then you should you the same id. Usually you don't need to invalidate session manually. If you don't invalidate it then it simply will be invalidated when app is terminated. If you need to cancel download task, then you could use `invalidateAndCancel` (to cancel outstanding tasks) or `finishTasksAndInvalidate` (to allow outstanding tasks to finish before invalidating the object). To use the session object after invalidating it you have to recreate session again using the same id we discussed above. – Vladimir Kaltyrin May 29 '18 at 15:28
  • Thank you for your explanation. Now i got some ideas about it. But i have another doubt. Now, my app return me error which state that `URLSession with identifier mySession already exists!`. For flow of app, when user click on button download then `viewDidload()` in other `viewController` that contain list of downloading file. And in that method has function that create session. Maybe it called so many times when button clicked so it return me error that id already exists! – Visal Sambo May 29 '18 at 15:41
  • @VisalSambo it's happen because you don't have to recreate session, you create one session and hold it until application is alive. Try to cancel download task instead, you don't have to invalidate session to just cancel the download. Sorry for my explanation above, it seems I didn't use proper words :) – Vladimir Kaltyrin May 29 '18 at 15:53
  • Sessions need to be cancelled if we want to change the `allowsCellularDownloads` property of the session. To resume data download we need to cancel the download task and fetch the resume data, then remove the original session also, then create a new session and then a new task using that resume data. The question here is if the original session identifier can be used when creating the new session; currently I'm getting the same error as @VisalSambo, "URLSession with identifier xxx already exists!". – Jonny Jan 30 '19 at 08:46
  • There's no need to include a namespace (e.g. "com.awesomeapps.appname") in the session identifier unless there's a concern with a conflict with downloaders in third-party components within your own app. The session identifier doesn’t need to be unique globally. – Edward Brey Nov 09 '20 at 06:00
0

Downloading Files in the Background recommends that you "use a small number of background sessions — ideally just one — and use these sessions to start many download tasks at once."

You'll need more than one session, however, if you need granular notification of download completion while your app is suspended. After all background transfers associated with the session have completed, the system resumes the app and sends the session identifier back to the app via the UIApplicationDelegate method application(_:handleEventsForBackgroundURLSession:completionHandler:).

The session identifier doesn’t need to be unique globally. If you have only one session, it doesn't matter what you pick.

Edward Brey
  • 40,302
  • 20
  • 199
  • 253