Hello Friends, have you ever wanted to download a file from an API to your user’s phone in the background? You might have faced a situation where you want to let your users download very large files from your server. And you want to download these sorts of files in the background. You might have also been in a situation where you just want to get data from an API, and you want to stream this data, either downloading or uploading the data, and you need full control of the streaming input/output and writing process. This post got you covered.

Download Data Streams to a File in the Background with Xamarin iOS

We will look at two methods to download files in the background with Xamarin iOS. The first will be the most reliable way, using NSURLSessionDownloadDelegate, where we let iOS control file location, and read/write processes to the file. The second way will let us control the full download process, from determining where the file is saved, to writing into it ourselves using streams we control entirely This will be done with NSUrlSessionDataDelegate.

Easy Background Download With NSUrlSessionDownloadDelegate

If you don’t care about uploading data or you want to download large files, and you don’t need to have full control of the stream read/write process of your data, then this is the way to go.

First, we create a delegate that inherits from NSUrlSessionDownloadDelegate. We then create an NSURLSession. This will be done by configuring it with an id and telling it to be in the background. NOTE: Only one NSURLSession instance should be created for a given Id.

You can then set the appropriate headers you want, the request method “Get, Post, etc…”. Next, you create a download task and start the download by resuming it.

You will surely need to update the UI as the download progresses, to keep your dear users updated. You do so by implementing the “DidWriteData” method of the delegate and updating the user as bytes are written.

You might ask yourself; how do I know where my downloaded file is stored? It is easy. When download terminates, the method “DidFinishDownloading” is called, and it passes to you a path to the downloaded file. You can now get this file, rename it or move it to its final destination.

Here is the full code of this delegate

Fully Control Data stream Download/Upload with NSUrlSessionDataDelegate

On iOS, the API provided to handle downloads is NSUrlSession. This API contains a set of helpers to facilitate not only to download files, but to download and upload data of any sort while the user is using the app or when the app is asleep. Since we want to literally stream data bytes from our API to the user’s mobile phone, we will need to manipulate raw input data streams from the API and output the data to a file stream on the user’s device. This use case is very similar to uploading raw data from our user’s devices to an API.

To accomplish this, we will create a class that inherits from “NSUrlSessionDataDelegate” this delegate will manage the download of the raw data stream. Then in its constructor, we configure the session. You can learn more about the NSURL API here

We want to precise the size of the buffer received from the server when data is read.

Before we start receiving data from our server, we need to configure an “NSMutableUrlRequest” by passing it authentication headers, the server’s URL then with this request, we create a “DataTask” that will start the download process as follows:

Before the download starts, we want to know important information as; the total size of data we will get from the server, if the initial request was successful or if it failed. To do so, we override the delegate’s method “DidReceiveResponse” which will be called to provide us with all of this information.

To calculate the download progress, and eventually notify our Users of the percentage of data downloaded and written locally to our file, we need to override another method of our delegate “DidReceiveData”. This method permits us to get the data downloaded bytes by bytes, and do whatever we want with this data.

Then, once the download completes, we want to know if it did so successfully, or an error occurred. We also want to close the file stream and dispose of it once we finish writing data to it. The method “DidCompleteWithError” is called when the download completes. No matter if the download succeeded with or without errors.

Once we are done coding this delegate, we can call it as follows;

Conclusion

We have seen how to download data streams to a file in the background with Xamarin iOS. This method is very similar to what is done when you want to upload data to a server as described in this Apple documentation. I really hope this will be helpful to you, please leave a like and subscribe to the notifications if you liked, and don’t forget to follow me on social media to stay updated. You might be interested in this article describing an advanced guide to sending push notifications from your backend to mobile devices with Firebase.

Follow me on social media and stay updated

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.