In today’s app development landscape, incorporating location-based services is becoming increasingly essential. Whether it’s for mapping, navigation, or providing location-specific content, GPS functionality enriches the user experience and adds significant value to mobile applications.
While integrating GPS might seem daunting at first, especially if you’re transitioning from web development to mobile platforms, NativeScript provides a seamless solution with the official @nativescript/geolocation
plugin. In this article, we will explore how to effortlessly add GPS capabilities to your NativeScript-Vue application using this powerful tool.
TL;DR: Sample working Vue 3 project is available on Github.
1. How it works technically
For Android, the package’s taking advantage of Google Play Services – Location API. Which is standard way nowsday to interact with GPS in the battery efficient way. But this also mean phones without Google Play Services, will not be able to use this package, such as Chinese phone maker like Huwei.
On other hand, on iOS, Core Location framework is being used.
2. Setup the package
The package can be installed easily by using:
npm i @nativescript/geolocation
After package is installed, next you are gonna need to setup proper permissions manifest for each platforms depend on how you are gonna need to interact with GPS functions.
For Android, add those lines to your AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
ACCESS_FINE_LOCATION
can be removed, if you don’t really need exact location of user. For example, News apps, Weather apps, etc. Where you properly just need to know which country or which is nearest town the user is located to suggest the relevent content.
If you need to continusely using GPS location in background, such user movement tracking application. You will need to add bellow extra permission, for Android:
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
For iOS background location access, add to plist:
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
(Notice: You don’t need to add anything to iOS plist if you are gonna access location in foreground only)
Pro tips
Rule of thumb, use fewer permissions is better, it would help you avoid headache during app review process. If you include ACCESS_BACKGROUND_LOCATION
in your Android app. You are gonna required to explain the usecase to Google review team and AppStore review team.
Silly me, there was a time I accidentally include background permission into my app, but don’t actually use it as we only get location during foreground. Don’t be me.
The package description itself already well explained its functions and how to use, so, also give it a read would be great idea: https://www.npmjs.com/package/@nativescript/geolocation.
3. How to use @nativescript/geolocation
3.1. Ensure you have permissions
Remember to always wrap your GPS operations in:
import * as geolocation from '@nativescript/geolocation';
geolocation.enableLocationRequest().then(() => {
// ... Safe to access Location API here
})
This ensure you always have enough permission interact with device’s location. Otherwise, access device’s location without permissions would result in fatal errors.
Pro tips
Never access Location API in your onMounted
hook (or mounted
for Vue 2). The problem is those hooks are called too soon, and some component may not booted properly yet! Instead, try using @loaded event on your <Page>
.
3.2. Read the location – the basic
Get device’s exact location once with:
import { CoreTypes } from '@nativescript/core';
// Notice: wrap below code inside `enableLocationRequest`
geolocation.getCurrentLocation({ desiredAccuracy: CoreTypes.Accuracy.high, maximumAge: 5000, timeout: 20000 })
.then((result) => {
// access latitude and longitude on `result` variable
// using: result.latitude, result.longitude, result.
})
for desiredAccuracy
, you have 2 options:
CoreTypes.Accuracy.any
: Use less power, expect above 100 meter accuracyCoreTypes.Accuracy.high
: More power hungry, the finest latitude & longitude the device can give
3.3. Read the location – the better way
A flaw with getCurrentLocation
is that it can sometimes take up to 10 seconds or even time out if the GPS signal is weak. I always use watchLocation
instead to avoid the timeout issue, and it also feels more intuitive to use alongside the Vue component lifecycle. Highly recommend using watchLocation()
, even if you’ll only need the location once.
Here is an example:
import { CoreTypes } from '@nativescript/core';
const location = ref<geolocation.Location | null>(null);
const watchId = ref<number | null>(null);
// Notice: wrap below code inside `enableLocationRequest`
geolocation.watchLocation(
(result) => {
// access latitude and longitude on `result` variable
// using: result.latitude, result.longitude, result.
location.value = result;
},
(error) => {
// something nasty happened
},
{
desiredAccuracy: CoreTypes.Accuracy.high,
maximumAge: 5000,
timeout: 20000
}
)
.then((id) => {
watchId.value = id;
});
Then, don’t forget to clear the watcher using clearWatch
, if you don’t know where exactly should you stop watching, it is good idea to clearWatch
inside your onUnmounted
hook:
onUnmounted(() => {
if (watchId.value) {
geolocation.clearWatch(watchId.value);
}
});
This ensures power efficiency and prevents zombie threads from running in the background.
Pro tips
In my shoes, I would start watching location change in @loaded event, before watchLocation
making sure there is no active watcher by checking watchId
, and use clearWatch
in onUnmounted
hook, to make sure whenever user leave the Page, it should be all well cleaned up.
Also, remember to access the device’s location reasonably to prevent taking a toll on the user’s precious battery consumption.
4. Conclusion
The GPS location feature is one of the most interesting aspects of the mobile world. Incorporating this feature into your project will provide users with a more immersive and personalized experience. However, it is also quite power-hungry, so use it wisely to prevent unnecessary power consumption.
Access GPS location in Background service, is also an interesting use-case for app such as Driver tracking, Delivery app, etc. I’m having another article cooking about Background service with NativeScript that’re gonna out soon, so stay tuned!