In this article we will guide you through the steps to build a Capacitor application with our advanced indoor positioning and tracking technologies. In case you have already integrated our plugin in your project, take a look at our Situm Cordova SDK documentation to learn how to use our api more in depth.
Pre-requisites: configure Capacitor #
- Install the Ionic framework:
In this guide we will be using Ionic. You can still integrate our plugin in an app without this framework, but we will be using it alongside capacitor to take advantage of their pre-built UI components and project structure templates.
To install it follow the installation guide by CLI. In this guide we are going to build an Angular application with tabs, so pick the Angular framework, the tabs template and the use of Standalone components when executing “ionic start”.
NOTE! Make sure you are using at least node 18.13 and @ionic/angular 7.5.0 to be able to build this proyect correctly. - (iOS only) Fill out the code signing of your project:
Inside Xcode go to your target and select the team that will be used to sign your app. Follow this guide to learn how to. - Run your project:
Once you have created your first project with the ionic CLI with the configuration mentioned before, you can now try the pre-built application with the following commands:
# For Android ionic cap run android # For iOS ionic cap run ios
This two steps should be enough to run the default ionic application. In case you face some unexpected issue, try to check the configuration steps on both Android and iOS platforms.
Congratulations! You have created a Capacitor + Ionic application. Now lets integrate our plugin in a few steps.
Installing the plugin #
Add our plugin to your project by executing the following command in your terminal:
npm install @situm/cordova
Setup native projects #
You will also need to make some changes to the native projects of your Capacitor application:
Android #
Add the ACCESS_FINE_LOCATION permission declaration to your AndroidManifest.xml (you can omit this step if you have configured Situm SDK not to use GPS):
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Finally, set the minSdkVersion to 22 at least on your app’s build.gradle file (android/app/build.gradle).
iOS #
First, you need to configure the required permissions (more info here), so include the following permissions in your app’s Info.plist file (modify the permission’s informative texts as you wish):
<key>NSLocationWhenInUseUsageDescription</key> <string>Location is required to find out where you are</string> <key>NSLocationAlwaysAndWhenInUseUsageDescription</key> <string>Location is required to find out where you are</string> <key>NSMotionUsageDescription</key> <string>We use your phone sensors (giroscope, accelerometer and altimeter) to improve location quality</string>
Modify your project’s Podfile (ios/App/Podfile) so our plugin works fine on iOS :
use_frameworks! :linkage => :static
Finally, you will need to add the underlying web application’s domain inside the entry WKAppBoundDomains, also on Info.plist as follows:
<key>WKAppBoundDomains</key> <array> <string>map-viewer.situm.com</string> </array>
If you have other webviews in your app this might affect them, you can learn more about this here.
Request permission #
You will also need to request the permissions we have just declared. In this guide we are using the cordova.plugins.diagnostic npm package to acomplish this task, but feel free to use other ways to ask for permission to the users:
npm install cordova.plugins.diagnostic
Run your app! #
There are many things you can do with the @situm/cordova plugin. In this guide, we will show you how to do the basic stuff. For more info, take a look at our sample app and at the plugin documentation.
Code snippets #
- Copy & paste this file into your tab1.page.html (src/app/tab1/tab1.page.html):
<ion-header [translucent]="true"> <ion-toolbar> <ion-title> Map Viewer </ion-title> </ion-toolbar> </ion-header> <ion-content [fullscreen]="true"> <map-view viewer-domain="https://map-viewer.situm.com" situm-api-key="YOUR_API_KEY" building-identifier="YOUR_BUILDING_IDENTIFIER" /> </ion-content>
- Copy & paste the following snippet into your tab1.page.ts (src/app/tab1/tab1.page.ts). Remember to add cordova.plugins.diagnostic as we will be requesting the app permissions to the user with this package. Also fill out the blank variables with your email, api-key, the identifier of your building and the identifier of a POI from your building:
import { CUSTOM_ELEMENTS_SCHEMA, Component } from '@angular/core'; import { IonHeader, IonToolbar, IonTitle, IonContent } from '@ionic/angular/standalone'; import { Platform } from '@ionic/angular/standalone'; // Declare a cordova variable to avoid typescript errors declare let cordova: any; const YOUR_SITUM_EMAIL = ''; const YOUR_SITUM_API_KEY = ''; const YOUR_POI_IDENTIFIER = ''; const YOUR_BUILDING_IDENTIFIER = ''; @Component({ selector: 'app-tab1', templateUrl: 'tab1.page.html', // Let the component know that we will use a custom HTMLElement. schemas: [CUSTOM_ELEMENTS_SCHEMA], styleUrls: ['tab1.page.scss'], standalone: true, imports: [IonHeader, IonToolbar, IonTitle, IonContent], }) export class Tab1Page { constructor(public platform: Platform) {} ionViewDidEnter() { // 1. Authenticate in our SDK. cordova.plugins.Situm.setApiKey(YOUR_SITUM_EMAIL, YOUR_SITUM_API_KEY); // 2. Use the remote configuration of your situm account. cordova.plugins.Situm.setUseRemoteConfig(true); // With this flag activated, you can modify your location request without any code changes. // See all the parameters you can modify in https://dashboard.situm.com/settings. // 3. Ask the user for permission before positioning. this._requestPermissions( () => { // 4. Start positioning. // You may want to specify a buildingIdentifier to locate the user inside a specific building. // When positioning starts, the map will automatically draw the user's position. cordova.plugins.Situm.onLocationUpdate((location) => { console.log("EXAMPLE> location update: ", location.position); }); cordova.plugins.Situm.onLocationStatus((status) => { console.log("EXAMPLE> location status: ", status); }); cordova.plugins.Situm.onLocationError((err) => { // Something went wrong while trying to start positioning on the device. // Handle the possible errors and notify the user so he can fix them. console.error("EXAMPLE> location error :", err); }); // Start positioning in the building specified at /src/constants.ts: cordova.plugins.Situm.requestLocationUpdates( // In case you have multiple buildings that the user could visit, // you might want to start positioning in all your buildings using global mode // by specifying an empty identifier. // Visit https://situm.com/docs/sdk-cartography/ to learn how to obtain your identifier. { buildingIdentifier: YOUR_BUILDING_IDENTIFIER } ); }, (errorMessage: any) => { console.error("ERR> ", JSON.stringify(errorMessage)); } ); // 5. Send actions to our viewer and handle events happening inside it. cordova.plugins.MapView.onLoad((controller: any) => { // MapView was loaded correctly, // now you can use our controller to manage our visual component. controller.selectPoi(YOUR_POI_IDENTIFIER); // In this case we are selecting some POI of a building. // You can find out what identifier has a certain POI of your building // by previously retrieving them with cordova.plugins.Situm.fetchIndoorPOIsFromBuilding(), // learn to use this method in our documentation (https://developers.situm.com/sdk_documentation/cordova/jsdoc/latest/situm#.fetchIndoorPOIsFromBuilding) }); } _requestPermissions(successCb: Function, errorCb: Function) { var isAndroid = this.platform.is("android"); var isIOS = this.platform.is("ios"); if (isAndroid) { cordova.plugins.diagnostic.requestRuntimePermissions( function (permissions: any) { console.log("EXAMPLE> permissions statuses: ", permissions); successCb(); }, function (error: any) { errorCb(JSON.stringify(error)); }, [ cordova.plugins.diagnostic.permission.ACCESS_FINE_LOCATION, cordova.plugins.diagnostic.permission.BLUETOOTH_CONNECT, cordova.plugins.diagnostic.permission.BLUETOOTH_SCAN, ] ); } else if (isIOS) { cordova.plugins.diagnostic.getLocationAuthorizationStatus( (status: any) => { if (status == "authorized") { successCb(); } }, () => { // Do nothing } ); cordova.plugins.diagnostic.requestLocationAuthorization( function (status: any) { switch (status) { case cordova.plugins.diagnostic.permissionStatus.NOT_REQUESTED: errorCb("Permission not requested"); break; case cordova.plugins.diagnostic.permissionStatus.DENIED_ALWAYS: errorCb("Permission denied"); break; case cordova.plugins.diagnostic.permissionStatus.GRANTED: console.log("Permission granted always"); successCb(); break; case cordova.plugins.diagnostic.permissionStatus.GRANTED_WHEN_IN_USE: console.log("Permission granted only when in use"); successCb(); break; } }, function (error: any) { errorCb(JSON.stringify(error)); }, cordova.plugins.diagnostic.locationAuthorizationMode.ALWAYS ); } } }
Finally, run your app with this command to launch the app on the device:
#For Android ionic cap run android #For iOS ionic cap run ios
If your followed step by step this guide your app should be asking for the permissions needed right after launching, and then start positioning in the building specified and painting positions in the map. You might face common configuration issues, so troubleshoot them by checking the logs with the web inspector.
Also make sure you have calibrated correctly your building to be able to draw indoor positions in the map view.