Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Support background transfers on iOS #4291

Open
1ec5 opened this issue Mar 12, 2016 · 19 comments
Open

Support background transfers on iOS #4291

1ec5 opened this issue Mar 12, 2016 · 19 comments
Labels
gl-ios iOS Mapbox Maps SDK for iOS macOS Mapbox Maps SDK for macOS offline refactor

Comments

@1ec5
Copy link
Contributor

1ec5 commented Mar 12, 2016

MGLOfflineStorage and associated APIs require the application to be open in order for the download to proceed to completion. Alternatively, the application can explicitly take power assertions to keep the application running in the background without being suspended or suddenly terminated. However, for large offline packs, even power assertions aren’t a great solution, because they require the entire application to run, impacting battery life.

iOS and OS X support background transfers, which allow the download to continue in a separate process while the application is suspended or terminated. ForeverMap 2 makes use of this feature, and it’s a decent experience on an iPad. The background transfer feature on iOS requires us to cede total control of the download to NSURLSession. Is that even feasible with the architecture we’ve created for offline downloads in mbgl?

/cc @jfirebaugh @boundsj

@1ec5 1ec5 added iOS Mapbox Maps SDK for iOS refactor macOS Mapbox Maps SDK for macOS offline labels Mar 12, 2016
@boundsj
Copy link
Contributor

boundsj commented Mar 13, 2016

I'm for using platform specific networking when possible because, as @1ec5 noted, there are some pretty big advantages for mobile scenarios (at least on iOS).

@postmechanical
Copy link

This was a huge limitation with MBXMapKit. Given the maturity of the NSURLSession APIs on iOS for background downloads, there's really no need to carry the limitations of the previous SDK over into this one.

@1ec5
Copy link
Contributor Author

1ec5 commented Mar 15, 2016

I'm for using platform specific networking when possible

In a sense, mbgl is using platform-specific networking, in that it’s all NSURL code under the hood. But mbgl itself abstracts away the difference between this networking code and the Android-specific networking code. I haven’t looked closely, but I think the primary difficulty will be plumbing through mbgl to the NSURL code when data is received in the background.

@jfirebaugh
Copy link
Contributor

Does background transfer require a monolithic download of a single URL? Offline downloads don't fit into that paradigm.

@1ec5
Copy link
Contributor Author

1ec5 commented Mar 15, 2016

I think it would support multiple URLs. Background transfers work through NSURLSession, which we’re already using, and a single NSURLSession supports multiple NSURLSessionDataTasks. We’d configure the session to accept background data. When it arrives, if the application has been killed (as opposed to suspended), the application is relaunched and -[UIApplicationDelegate application:handleEventsForBackgroundURLSession:completionHandler:] gets called (lots of nuance in that API documentation). MGLOfflineStorage would provide a method that the developer would have to call from within their implementation of -application:handleEventsForBackgroundURLSession:completionHandler:, and I’m sure there would be gymnastics at the mbgl level to recreate its state.

@jfirebaugh
Copy link
Contributor

OfflineDownload doesn't really have a way to recreate its state other than by restarting the download process from the beginning and checking what resources already exist in the database. At one point I had built a secondary, database-only pathway to short circuit portions of this process, but it turned out to introduce more complexity than it was worth.

@1ec5
Copy link
Contributor Author

1ec5 commented Mar 15, 2016

When I resume a paused download, mbgl::OfflineDownload has to start from the beginning? That matches what I’ve been observing in iosapp, but I didn’t realize it was a fundamental limitation.

I do think the battery savings and reliability of background transfers would be valuable enough to warrant some additional complexity, but I’m not familiar enough with the offline storage design in mbgl to make a call on that. In the meantime, as a workaround, MGLOfflineStorage – or indeed the application code itself – could begin a background task for the duration of the download.

@Craigelcocoa
Copy link

Hi, does anyone have an example of how to download the offline maps using an NSURLSession? If this example could show how to download > 1 map in a loop or queue that would be eveb better.

Apologies if this is fairly obvious to most but i'm reasonably new to obj-c in general. My app needs to download 6 offline maps, which i can do, but i need it to happen in the background in case the user doesn't keep the screen alive while this happens as this caused a crash during testing. The only way i know how to use NSURLSession would be to set up some data tasks and then supply a url but the only way i know how to start an offline map download is to create a pack and call resume on it. Therefore, i have no URL to give the NSURLSession to run the download job???

@Craigelcocoa
Copy link

An alternative of course would be to run each map download as a finite length background task in a loop but that provides no guarantee that you will be given enough time for the map download to complete

@postmechanical
Copy link

@Craigelcocoa The UIKit background task API does not provide enough time to complete an offline map download. The best you can do when app enters background is to create a background task that pauses any active map downloads and then resume those downloads when the app subsequently activates. The only way for offline map downloads to truly work in the background is for the Mapbox-iOS-SDK to implement downloads using NSURLSessionDownloadTask.

@Craigelcocoa
Copy link

Hi thanks for the reply, much appreciated. Hopefully, NSURLSessionDownloadTask will be added to the mapbox sdk in the near future

@robertodias180
Copy link

any way to achieve this in the current version?

@yueno12
Copy link

yueno12 commented Nov 30, 2017

+1

@noramimiyuma
Copy link

I hope that MGLOfflinePack will be able to caching in the background.

@ArtiPatel10
Copy link

Is there any progress in this thread?

@stale stale bot added the archived Archived because of inactivity label Dec 26, 2018
@stale
Copy link

stale bot commented Dec 26, 2018

This issue has been automatically detected as stale because it has not had recent activity and will be archived. Thank you for your contributions.

1 similar comment
@stale
Copy link

stale bot commented Dec 26, 2018

This issue has been automatically detected as stale because it has not had recent activity and will be archived. Thank you for your contributions.

@stale stale bot closed this as completed Dec 26, 2018
@1ec5
Copy link
Contributor Author

1ec5 commented Mar 5, 2019

Though the offline pack sideloading mechanism does mitigate this issue somewhat, end users still expect to be able to switch applications or lock the screen while an application downloads offline packs, and developers don’t intuitively expect to have to keep the screen alive.

@1ec5 1ec5 reopened this Mar 5, 2019
@stale stale bot removed the archived Archived because of inactivity label Mar 5, 2019
@georgbachmann
Copy link

I fully agree with @1ec5 ! This limitation is quite annoying for users. Is there any progress yet?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
gl-ios iOS Mapbox Maps SDK for iOS macOS Mapbox Maps SDK for macOS offline refactor
Projects
None yet
Development

No branches or pull requests