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.
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.
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.
The next step is to register our background mode and background identifiers inside info.plist
file
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.
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.
AppDelegate code you may find at the repository.
And two last things we need to do:
- When the system Performs Fetch, we need to return information is any new data was available or not.
2. Submit a Request to Background Scheduler about our shared background worker, which we set up inside FinishedLaunching
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
Important here is to set and later request Location Always
if we want to receive location updates in the background
Now we can setup location updates by subscribing to the event LocationsUpdated
at CLLocationManager
.
To make that, we need:
- Create instance of
CLLocationManager
- Disable automatic location pauses
- Additionally to our permission request — we need to request always authorisation if the system version is higher than 8 (so every time 🤪)
- And if the system version is higher than 9 (so every time 🤪) we need to allow background location updates
- After that, if location services are available, we may set the desired accuracy and subscribe for location updates
- 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:
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 😝.
- Create instance of
CLLocationManager
- Disable automatic location pauses
- Additionally to our permission request — we need to request always authorisation if the system version is higher than 8 (so every time 🤪)
- And if the system version is higher than 9 (so every time 🤪) we need to allow background location updates
- After that, if location services are available and monitoring service is available
- We may set the desired accuracy and subscribe to
region
events - 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.