I present to you… an app that can record all your car drives automatically.
This has been a tiny hobby project of mine – to make an app, that would automatically record all the car drives I make, and be able to export some “useful” data to email.
How does it work.
1.) App needs “Location Updates” and “Background processing” capabilities
2.) App needs to get location access (ALWAYS USAGE)
3.) App needs to get motion access (to distinguish when the device is in driving mode)
4.) LocationManager -> pausesLocaationUpdatesAutomatically = false
5.) LocationManager -> allowsBackgroundLocationUpdates = true
6.) LocationManager -> activityType = .automotiveNavigation
7.) Motion API checks for activity.
7.1.) If it is driving, then LocationManager -> desiredAccuracy = kCLLocationAccuracyBestForNavigation
7.2.) If it is not driving, then: LocationManager -> desircedAccuracy = kCLLocationAccuracyThreeKilometers
With these things, the app will be able to work in the background, and not use GPS, while the device is not in driving mode (it will instead use phone towers to triangulate approximate location, but it is not too important), and when driving, it will switch to best navigation.
From my testing, it still happens that iOS closes your app. When that happens, in my experience, it rarely opens the app again.
So, for extra safety:
8.) MONITOR VISITS!
LocationManager -> startMonitoringVisits(). This will hopefully force iOS to launch the iOS app in the background again. This works, but the data is useless in this case. I just used this in the hopes that the iOS would launch this app in the background.
9.) REGION MONITORS!
Whenever the app detects that an active car drive has ended, it sets up a region monitor with a radius of 100 meters for both exit and entry. These region monitors are not precise because they use phone towers, but this is another helpful way to open the app again in the background whenever we enter the car area again (or maybe we never left the car area, but now we are driving away, and it did not start to record the drive, then it will start once we leave the region). Again, not perfect, but every bit helps.
To help the application stay alive when launched in the background, every time the app is cold started, I activate GPS for 10 minutes to make iOS believe that it is necessary to keep it alive.
10.) LOCAL NOTIFICATIONS!
With the help of a timer, add UNMutableNotificationContent to notify the user when the app has stopped running in the background. (TODO: need to check if instead of timer, maybe applicationWillTerminate: will also work).
But anyway, this is a last resort helper for me. In the event that the app stops working, I receive a notification about it, informing me to launch the app manually to continue tracking it in the background. In my tests, app has never closed mid-drive, but instead, when I have not driven for some time, or using extensively other iOS apps, that take up RAM.)
WHAT MORE COULD I TRY? (Things I have not tried yet)
11.) Background content downloading!
By integrating performFetchWithCompletionHandler: into the AppDelegate, iOS could, at some random times, call this function to allow your app to download some content. Instead – just return .noData or .newData, and just be happy that the app has started working in the background again.
12.) VOIP notifications
I could rig up either a server sending some VOIP pushes from time to time to wake the app, or maybe use those silent pushes (but those are also not always getting through).
13.) One more thing.. but while I wrote other things, I forgot about this one.
I will add later.
Keep in mind, that Motion API can detect driving mode from the GPS movement itself, but it takes some time.
In my case, my phone connects to car Bluetooth, and that seems to be the primary thing for Motion API. Even if I stop the car (without turning it off), and walk around the car, while still connected to car Bluetooth – I am still in a driving mode.
The app is just a barebones demo. There is so much more I wanted to add, but.. then it becomes like a full-time job.. so.. meh.
But for giggles.. I live in a place with a gate that is openable by calling a phone number. So, I also rigged up this application so that every time a car location is within the gate radius, it auto-calls (via some REST API’s + TWILIO STUDIO) the gate! MAGIC!
I am also thinking of rigging it up for running activities (like, if I am running, it could also actively track the GPS and open the gates automatically). But maybe that is for a different app.
If you have thought of something more than what I came up with (to make an app work in the background in a more stable way, or so that the app would use less battery), then reach out to me!