Install SDK on iOS
Add HyperTrack SDK to your project
Swift Package Manager
Select File
> Swift Packages
> Add Package Dependency...
. Enter this URL https://github.com/hypertrack/sdk-ios
in the search field to install the dependency.
Swift Package Manager is supported in Xcode 12 and up.
CocoaPods
If you don't have CocoaPods installed, you can install it here.
Using command line run pod init
in your project directory to create a Podfile. Put the following code (changing target placeholder to your target name) in the Podfile:
note
We constantly work on making our SDKs better, so make sure you have the latest version of it. You might take a look of its changelog here.
Run pod install
. CocoaPods will build the dependencies and create a workspace (.xcworkspace
) for you.
If your project uses Objective-C only, you need to configure SWIFT_VERSION
in your project's Build Settings. Alternatively, you can create an empty Swift file, and Xcode will create this setting for you. Set Swift version to 5
. Additionally change pod 'HyperTrack', '4.7.0'
to pod 'HyperTrack/Objective-C', '4.7.0'
in your Podfile.
Enable background location updates
Enable Background Modes in your project target's Capabilities tab. Choose "Location updates".
Handle location and motion permissions
Set the following purpose strings in the Info.plist
file:
HyperTrack SDK requires "Always" permissions to reliably track user's location. Be advised, purpose strings are mandatory.
Your app needs to make sure that it has location and motion permissions for location tracking to work. See this F.A.Q. page for details on permissions best practices.
Initialize the SDK
Get your publishable key from the Setup page.
Put the initialization call inside your AppDelegate
's application:didFinishLaunchingWithOptions:
method:
Swift
Objective-C
Import the SDK:
Initialize the SDK.
NSNotifications
Restorable and Unrestorable error notifications are called if the SDK encounters an error that prevents it from tracking. SDK can recover in runtime from Restorable errors if the error reason is resolved. Errors include:
- Initialization errors, like denied Location or Motion permissions (
RestorableError.locationPermissionsDenied
) - Authorization errors from the server. If the trial period ends and there is no credit card tied to the account, this is the error that will be called (
RestorableError.trialEnded
) - Incorrectly typed Publishable Key (
UnrestorableError.invalidPublishableKey
)
Swift
If you want to handle errors using the same selector:
If you want to handle errors separately, or handle only Restorable or only Unrestorable errors:
Objective-C
If you want to handle errors using the same selector:
If you want to handle errors separately, or handle only Restorable or only Unrestorable errors:
You can also observe when SDK starts and stops tracking and update the UI:
Swift
Objective-C
Enable remote notifications
The SDK has a bi-directional communication model with the server. This enables the SDK to run on a variable frequency model, which balances the fine trade-off between low latency tracking and battery efficiency, and improves robustness. For this purpose, the iOS SDK uses APNs silent remote notifications.
note
This guide assumes you have configured APNs in your application. If you haven't, read the iOS documentation on APNs.
Configure APNs on the dashboard
Log into the HyperTrack dashboard, and open the setup page. Upload your Auth Key (file in the format AuthKey_KEYID.p8
) and fill in your Team ID.
This key will only be used to send silent push notifications to your apps.
Enable remote notifications in the app
In the app capabilities, ensure that remote notifications inside background modes is enabled.
In the same tab, ensure that push notifications is enabled.
important
Silent push notifications will work even if users deny notification permissions in the app. The only way to disable them is to disable "Background App Refresh" in Settings or to turn on "Low Battery Mode".
Registering and receiving notifications
The following changes inside AppDelegate will register the SDK for push notifications and route HyperTrack notifications to the SDK.
Register for notifications
Inside didFinishLaunchingWithOptions
, use the SDK method to register for notifications.
Swift
Objective-C
Register device token
Inside and didRegisterForRemoteNotificationsWithDeviceToken
and didFailToRegisterForRemoteNotificationsWithError
methods, add the relevant lines so that HyperTrack can register the device token.
Swift
Objective-C
Receive notifications
Inside the didReceiveRemoteNotification
method, add the HyperTrack receiver. This method parses only the notifications sent from HyperTrack.
Swift
Objective-C
If you want to make sure to only pass HyperTrack notifications to the SDK, you can use the "hypertrack" key:
Swift
Objective-C
Start tracking
Now the app is ready to be tracked from the cloud. HyperTrack gives you powerful APIs to control device tracking from your backend.
To use the HyperTrack API, you will need the
{AccountId}
and{SecretKey}
from the Setup page.
Track devices during work
Track devices when user is logged in to work, or during work hours by calling the Devices API.
To start, call the start API.
Get the tracking status of the device by calling GET /devices/{device_id} api.
To see the device on a map, open the returned embed_url in your browser (no login required, so you can add embed these views directly to you web app). The device will also show up in the device list in the HyperTrack dashboard.
To stop tracking, call the stop API.
Track trips with ETA
If you want to track a device on its way to a destination, call the Trips API and add destination.
HyperTrack Trips API offers extra fields to get additional intelligence over the Devices API.
- set destination to track route and ETA
- set scheduled_at to track delays
- share live tracking URL of the trip with customers
- embed live tracking view of the trip in your ops dashboard
To get {longitude}
and {latitude}
of your destination, you can use for example Google Maps.
HyperTrack uses GeoJSON. Please make sure you follow the correct ordering of longitude and latitude.
The returned JSON includes the embed_url for your dashboard and share_url for your customers.
When you are done tracking this trip, call complete Trip API using the trip_id
from the create trip call above.
After the trip is completed, use the Trips API to retrieve a full summary of the trip. The summary contains the polyline of the trip, distance, duration and markers of the trip.
Track trips with geofences
If you want to track a device going to a list of places, call the Trips API and add geofences. This way you will get arrival, exit, time spent and route to geofences. Please checkout our docs for more details.
Dashboard
Once your app is running, go to the dashboard where you can see a list of all your devices and their live location with ongoing activity on the map.
Optional steps
Identify devices
All devices tracked on HyperTrack are uniquely identified using UUID. You can get this identifier programmatically in your app by calling deviceID
after initialization.
Another approach is to tag device with a name that will make it easy to distinguish them on HyperTrack Dashboard.
Swift
Objective-C
You can additionaly tag devices with custom metadata. Metadata should be representable in JSON.
Swift
Objective-C
Add a geotag
Use this optional method if you want to tag the tracked data with an event that happened in your app. E.g. user marking a task as done, user tapping a button to share location, user accepting an assigned job, device entering a geofence, etc.
The process is the same as for device metadata:
Swift
Objective-C
Frequently Asked Questions
Please review this guide to get answer to these questions:
- Why doesn't my iOS app start tracking in the background state?
- Why did my iOS app stop tracking?
- Why does my application state disappear when my app is opened?
- What are the best practices for handling permissions on ios
- Why access to activity services has not been authorized
Why doesn't my iOS app start tracking in the background state?
Make sure your app has location and motion permissions to start tracking.
Get permissions before your app is in the background state
For example, if your app does the following steps:
- User logs in
- Starts a shift
- App calls your app backend which calls HyperTrack API to create a trip
then at this point the app can already be in the background because the user has already switched to other tasks. HyperTrack cannot start tracking on the device for the trip as permissions cannot be requested while the app is in the background state.
important
If location and motion permissions are not granted in the foreground prior to the app going to the background state, HyperTrack SDK cannot request them to start location tracking in your app in the background state.
That’s why it’s important to make sure that the app has all required permissions before the user can start a shift.
To make this happen, your app needs to use CLLocationManager
and CMMotionActivityManager
to request authorization.
Usually apps detect current permissions state first and, if they are not granted, show a special screen allowing the user to grant them right there, or if they were denied to switch them on in Settings.app
.
This way, when the user starts a new shift, push notification would reach the app, the app would have all the necessary permissions to track.
Why did my iOS app stop tracking?
OS regularly drops application memory when it needs more memory for the app currently in foreground.
Test memory usage on device
Quickest way to check this is to run a game or open a Camera app and record a video. The OS sorts all apps frozen in the background by memory footprint and starts dropping memory one by one starting with the largest ones.
When iOS does this, it creates a file called "JetsamEvent", which you can see in Settings
> Privacy
> Analytics & Improvements
> Analytics Data
.
For more details see this Apple Developer Note.
note
This is typical iOS behavior and no app can assume that the OS will always keep memory for frozen apps.
iOS versions 13.2 and 13.2.1 had a bug which caused the scheduler to drop memory for the frozen apps more aggressively.
Also, your app should not rely on memory to be preserved and should store and then restore their state when the user launches the app.
Sometimes application bugs, like memory leaks, can cause the app to consume a lot of RAM, and become one of the first apps in the iOS list for the memory reclaim process.
Prevent excessive memory usage on iOS device
To prevent this, your app should be regularly profiled in Xcode using Instruments tool, configured with Leaks
preset. It provides two views into the app memory called Allocations and Leaks.
Allocations allow you to see how much RAM your app is consuming and how this size grows and shrinks in response to user actions.
Leaks
tool automatically reports when memory is created and would never be freed. HyperTrack SDK profiled in Instruments consumes under 1 MB of RAM and doesn't have memory leaks.
Good starting point can be Instruments documentation by Apple. iOS also sends low memory warnings to the app when it detects that it consumes too much.
It's also useful to checkout Apple guide on improving your app's performance.
If you’ll find any instances of HyperTrack SDK consuming too much RAM, or being a reason for abrupt terminations, please do not hesitate to contact us and provide crash reports or Instrument
analysis files. Instruments
sessions can be saved and shared.
Prepare your app to run in the background
iOS can also abruptly terminate the app upon entering the background. This can happen if, upon entering background, the app does not free resources and does not stop long running tasks, like timers and network requests.
The app without a reason to stay in the background has only a couple of seconds to stop all its activities and if it fails, the OS will force the termination.
The following guide by Apple provides all the steps the app needs to do upon entering background and can serve as a checklist.
Why does my application state disappear when my app is opened?
App state is not preserved in the background
App does not hold state when it goes to the background state. When the user returns to the app, it starts from scratch. iOS stops executing an app and freezes its memory when the user hides the app's screen.
The only exceptions are apps that actively do background work, such as:
- downloading content
- VoIP calls
- active location tracking
There are three things that can happen to the app in a stopped and frozen state:
- The app's memory is stored in RAM and when the user returns to the app execution continues where he left off
- OS drops the app's memory, so when the user returns, the app needs to restore state manually
- OS terminates app execution abruptly, crashing the app in the background
important
This is typical iOS behavior and no app can assume that the OS will always keep memory for frozen apps.
iOS versions 13.2 and 13.2.1 had a bug which caused the scheduler to drop memory for the frozen apps more aggressively.
Apps shouldn't rely on memory to be preserved and should store and then restore their state when the user launches the app.
A good starting point to learn how to manage restoring app state is newly updated UI state restoration guide.
What are the best practices for handling permissions on iOS?
In Human Interface Guidelines Apple recommends the following instructions below:
Request permissions only when they are needed in the flow of the app
If you app is centered around location tracking, then asking for permissions at the app launch can be understandable for users. On the other hand, if location tracking is just one of the features, then it makes sense to request them only when the feature is activated.
Provide short and specific purpose string
Purpose string should explain the value that location and motion tracking provides. Examples of motion tracking benefits: improves battery life by using algorithms based on motion tracking data, provides story-like details for historical tracking data, gives live feedback on current activity.
In addition a lot of great apps provide a special screen explaining the need for permissions before asking them. If permissions are denied you can guide the user to the specific page in the Settings.app to change permissions (see this guide for special deep-links for the Settings.app).
"Provisional Always" authorization state
On iOS 13 Apple introduced a new "Provisional Always" authorization state (see this StackOverflow answer for details).
In short:
- there is no API to detect this state
- during this state there are no location events in background
- user sees his permissions as granted and sees "While Using" state in Settings.app
- app sees permissions as granted with "Always" state.
HyperTrack is working on ways to detect this state and provide APIs that would enable app developers to display explanation screens that will guide the user back to Settings.app to switch permissions from "While Using" to "Always".
Why Access to Activity services has not been authorized?
You are running the Quickstart app on the iOS simulator, which currently does not support CoreMotion services.
important
You can test the app on real iOS devices only.