Nerd For Tech
Published in

Nerd For Tech

Background Work in Xamarin.Forms. Part #2 — Xamarin.iOS

This time we will cover possible solutions to run something in Background for iOS Devices. We will touch on location updates and region monitoring because it’s the most common case.

Hello Folks 👋!!! As mentioned in the sub-title we will touch on location updates and region monitoring because it’s a most common cases, but other updates like Background Push notifications, Audio or AirPlay will not be covered because it’s quite specific for their usage and better for the device on their own, separate blog posts.

Task.Run — native .Net way to run Background tasks was nicely covered at Part #1 and I would like just mentioned that it does the same possibilities for iOS and quite the same advantages and limitations. One important thing to mention here is that it stops executing all background tasks shortly after the iOS application has been hidden. That’s why if you want to ensure you are finished your work or your task can take some notable time, you need to use BGTaskScheduler.

All source code for both parts is available at GitHub:

Run Native Background Task with BGTaskScheduler

Before we begin, I need to mention that we will implement the IBackgroundWorker created and used in Part #1 of the blog. Please go there and copy its definition.

To show how it works, I will create repetitive work. That Background work will just get nothing and log into screen time when it was invoked.

Background Work Updates

To achieve this, we need to set up NSTimer -> CreateRepeatingScheduledTimer with some cooldown. For this example, I will use 5 seconds, but apple recommends using from 5 to 15 minutes for such repeats, but if your task needs more time for execution or some longer delay, 30 minutes may also work.

CreateRepeatingScheduledTimer definition

As an action, we will pass the function where we were going to create taskId with a time expired callback to ensure we finish that task.

Setup of NSTimer

The next step is to register our background mode and background identifiers inside info.plist file

info.plist settings for background task updates

The next step is to register our Background Worker inside AppDelegate -> FinishedLaunching. Here we need inside shared task scheduler register by our CFBundleIdentifier new NSOperationQueue. And inside the shared application, set the minimum background to fetch interval. Recommended here is to use UIApplication.BackgroundFetchIntervalMinimum provided by the iOS.

Refresh Identifier Constant
AppDelegate FinishedLauching Method

Our launch handler task will ask if any work is available from our Background Worker and run it if any will be available. This all will be executed in the background when our app is hidden.

But the iOS system will never call your Background work if you completely close your app, for that you need to search for a workaround with some custom push notifications or kind of that.

Start Background Synchronisation Work
Background Worker implementation

AppDelegate code you may find at the repository.

And two last things we need to do:

  1. When the system Performs Fetch, we need to return information is any new data was available or not.
Perform Fetch method

2. Submit a Request to Background Scheduler about our shared background worker, which we set up inside FinishedLaunching method

Did Enter Background method

Location Updates in iOS

This time let’s start with info.plist setup. We need to set the location usage description and one more background mode

info.plist settings for background location updates and region monitoring

Important here is to set and later request Location Always if we want to receive location updates in the background

Request Location Always Permissions
Location and Region Work Updates

Now we can setup location updates by subscribing to the event LocationsUpdated at CLLocationManager.

To make that, we need:

  1. Create instance of CLLocationManager
  2. Disable automatic location pauses
  3. Additionally to our permission request — we need to request always authorisation if the system version is higher than 8 (so every time 🤪)
  4. And if the system version is higher than 9 (so every time 🤪) we need to allow background location updates
  5. After that, if location services are available, we may set the desired accuracy and subscribe for location updates
  6. After all that, we can start updating the location 🤩

As you may notice, I checked the last execution time and ran my own event only once per some time(delay). If you would like to receive any location updates(event multiple times per second if you are on the highway), just remove that if and all still will be fine for you.

Here is how it looks like by simulating Freeway Drive comparing to the previous simulator screenshot:

Update location all the time without any delay

Region Monitoring in iOS

Surprise, surprise here is mostly the same we had for location updates, same permissions, same info.plist modifications. So let’s jump immediately into the meat part 😝.

  1. Create instance of CLLocationManager
  2. Disable automatic location pauses
  3. Additionally to our permission request — we need to request always authorisation if the system version is higher than 8 (so every time 🤪)
  4. And if the system version is higher than 9 (so every time 🤪) we need to allow background location updates
  5. After that, if location services are available and monitoring service is available
  6. We may set the desired accuracy and subscribe to region events
  7. After all that, we can start updating the location 🤩

This is all I want to cover in this cycle of two blog posts 😆 about running some common background tasks in Android and iOS. Hope all that will help you to decide when to use .Net Task.Run and when goes with native solutions.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store