The Background Transfer Service in iOS is a service that allows your app to download or upload large amounts of data in the background with no time limits. Whether your app is in the foreground, suspended, or sitting in the background, it can download as much data as it wants without the time limits that iOS enforces with other mechanisms.
When using the Background Transfer Service, you are essentially allowing iOS to take control of your download. Depending on external factors, such as available resources, interruptions, network connectivity, battery life, etc., iOS will decide when to give your application time to process network content. While the download/upload is in progress, iOS will periodically ping your application to inform current status or errors.
By relinquishing control of the network transfer to the operation system, you lose some predictability and speed, but you gain a lot of extra flexibility and power with regard to your web traffic.
3. Create the
4. Hook into the
When using the Background Transfer Service, you are essentially allowing iOS to take control of your download. Depending on external factors, such as available resources, interruptions, network connectivity, battery life, etc., iOS will decide when to give your application time to process network content. While the download/upload is in progress, iOS will periodically ping your application to inform current status or errors.
By relinquishing control of the network transfer to the operation system, you lose some predictability and speed, but you gain a lot of extra flexibility and power with regard to your web traffic.
The backbone of the Background Transfer Service is implemented using the
NSUrlSession
API. To use this API, you must create a download/upload session along with a set of background tasks (or just a single task) to actually do the work. These tasks are instances of NSURLSessionTask
objects. The session also requires a delegate—an instance of NSUrlSessionTaskDelegate
, which is how iOS communicates with your application.The Basics of Background Transfer Service
Let’s update the example from my previous post, using the Background Transfer Service, rather than
HttpClient
, to fetch the image.1. Create the background session object.
In order to use the
NSUrlSession
API, we need to first create and configure an NSUrlSession
object. As you can see below in the ConfigureBackgroundSession
method, we use BackgroundSessionConfiguration
to check if there is an already-configured session. If so, we can just use that. Otherwise, we create a new background session configuration with CreateBackgroundSessionConfiguration
and pass in a session ID, which is just a unique string. If you try to create a session with a session identifier that already exists, iOS will not create a new session configuration.
Once we have our
NSUrlSessionConfiguration
, we can use this configuration to create the session object. Creating the session is quite simple—just use the NSUrlSession.FromConfiguration
static method. This method requires the instance of your configuration object as well as a delegate, which will be used as the interface between iOS and your application. This UrlSessionDelegate
will be defined later.
C#
2. Kick off the download task(s).
Once you have the session configured, the next step is to kick off some download tasks. In our case, we only need one task, but if we were to be downloading multiple files, it would be best to utilize multiple download tasks. This
FetchImage
is the same method used in my previous post, but I have removed the call to HttpClient
. Instead, we are creating the NSUrlSession
and initializing a download task.
The
CreateDownloadTask
method is used to create a download task on a background session. It is important that you call Resume
on the task to start the asynchronous download. You can also cancel and resume the download at any point.
C#
3. Create the NSUrlSessionDelegate
.
Now that we have the session configured and the download tasks running, we need to implement the
NSUrlSessionDelegate
class to allow iOS to communicate status back to our app and for our app to inform iOS when it is all done. Since we are using an NSUrlSessionDownloadTask
, we will implement an NSUrlSessionDownloadDelegate
delegate.
Below is a basic implementation of a
UrlSessionDelegate
. In the constructor, we just set the file path where we want the image stored. This is the same location as in the earlier example. Then, we implement the DidWriteData
, DidFinishDownloading
and DidFinishEventsForBackgroundSession
delegate methods. Depending on the needs of the application, there are several other optional methods that could be implemented.
C#
The
DidWriteData
method is called periodically throughout the download process. It reports the number of bytes written in this chunk, the total number written by this task, and the total expected bytes to be received. This is a really useful method for reporting download progress. We are just calculating the progress and printing the percentage to the console.
The
DidFinishDownloading
method is called once the task has finished downloading all data. The task will write its data to a temporary file in the file system. It is up to you to copy that file to a more permanent location, if required. Once control leaves this method, the temporary file will be deleted. If you have multiple download tasks running concurrently, be sure to check that the task is the expected task before processing the data.
The
DidFinishEventsForBackgroundSession
method is a very important one, and it is the final step in a Background Transfer. This is where you can perform any last-minute processing or UI updates before iOS puts you in the background (assuming your app is in the background when this runs). Once you have performed all necessary processing of the downloaded content, you must call the completion handler. Which brings us to…
4. Hook into the AppDelegate
.
Before iOS actually starts downloading your content, it will call the
HandleEventsForBackgroundUrl
delegate method and pass in a completion handler.
C#
This completion handler is not to be confused with the completion handler passed into the
PerformFetch
delegate method. This completion handler is used to tell iOS when the background transfer is complete, and you are ready to go back to the background. All we need to do in the HandleEventsForBackgroundUrl
method is save off the completion handler. It must be called from DidFinishEventsForBackgroundSession
(see above).Looking Down the Road with Xamarin
The Background Transfer Service is a powerful feature of iOS which, if used correctly, can greatly enhance the user experience of your application. It allows developers to be flexible with our timing requirements and lets large and unpredictably sized downloads or uploads happen in the background.
This was a very basic example to demonstrate and explain the iOS Background Transfer Service, especially as it relates to Xamarin’s implementation. In my experience with Xamarin so far, it has proven a very painless exercise to implement background services, and I am excited to see what the future has in store for Xamarin.
No comments:
Post a Comment