Introduction
Naurt's dynamic iOS SDK enhances standard GNSS location fixes for devices in motion.
It offers:
- Enhanced precision
- Location fixes in times of GNSS outage
- Spoofing reports
- Heading and speed outputs
- Uncertainties on all outputs
Naurt's outputs are also consistent across devices, meaning no matter what SDK you use, we output the same information.
No more writing code that handles iOS and Android location managers differently.
Naurt's outputs are consistent throughout time. Say you're entering a tunnel, the standard GNSS location manager
may stop outputting location fixes. This isn't the case with Naurt - our technology ensures you receive constant
location
update when traveling from outside to inside.
What to expect
Here's an example of what to expect from Naurt's dynamic SDK. Below, we have a plot of heading output, location output,
and speed output. As you can see Naurt, vastly improves the reliability of the outputs and also offers an error range
showing the confidence of the outputs.
At the end of the day, Naurt's SDKs are optimisation tools. Bad data will look better, and good data will great. There
is
no across the board guarantee we can make.
If you would like to test Naurt before going any further with integration, please checkout our demo app
which can be found on our Github.
Important
Even though Naurt can be run via the simulartor - you can not make any guage of
performance from the simulator. Locations and sensor readings can not be accurately
simulated. For any tests of Naurt performance, please use a real phone outdoors
Update Dependencies
Naurt requires the following dependencies be added to your project.
Naurt no longer requires the swift-collections
package
XCode App
If you are making an app in XCode, then you need to add dependencies by
clicking on the project, navigating to the Package Dependencies
tab and adding the dependencies with the plus icon. It should look like the
following screenshot
Then, these dependencies need to be added to the target. Click the app target
and navigate to Build Phases
, and add them as dependencies in
the Link Binary With Libraries
section, and add as dependencies
with the plus icon. Make sure they are all Required
. It should
look like the following screenshot (we will deal with the framework in a
moment).
SPM
If you are making a package with SPM, place the following snippet in your
Package.swift
file.
dependencies: [
.package(url: "https://github.com/marmelroy/Zip", from: "2.1.2"),
.package(url: "https://github.com/alexandertar/LASwift", from: "0.2.6"),
],
Cocoa Pod
The Naurt Cocoa Pod should handle dependencies for you
Carthage
Coming soon
Add Framework
Since Naurt is a closed source binary, it is distributed as an
xcframework
. This folder contains two framework
folders. One is for the Iphone deployment, and the other for the
simulator.
The frameworks can be found here https://github.com/Naurt-Ltd-Public/Naurt.swift
XCode App
If building an XCode app, the easiest way to integrate Naurt is to drag the
NaurtSDK.xcframework
folder from Sources
in the
repository into the Frameworks, Libraries, and Embedded Content
section of the General
section of the app target.
It should look like the following screenshot
SPM
If making an SPM package then use the following snippet in your
Package.swift
file
dependencies: [
.package(url: "https://github.com/Naurt-Ltd-Public/Naurt.swift.git", from: "0.0.8"),
],
Cocoa Pod
If using CocoaPods, then add this snippet to your Pod file
pod "Naurt.swift", "~> 0.0.8"
Carthage
Coming soon
App Configuration
When making an app, ensure that the following steps are taken to give
Naurt all required permissions.
Under Signing and Capabilities
of the app target,
add a Background Modes
section, and tick
Location Updates
and Background processing
.
It should look like the following
The, in the Custom iOS Target Properties
section of
Info
section of the app target, you need to add the following
items with the plus icon, and add a description. The description should tell
the user of the app why location permissions are necessary, and allow them
to make an informed decision about whether they wish to grant permissions
for the functionality.
- Privacy - Location When In Use Usage Description
- Privacy - Location Always Usage Description
- Privacy - Location Always and When In Use Usage Description
It should look like the following screenshot
Design Pattern
Naurt uses a delegator design pattern. Essentially, after making the Naurt
object, you will be declaring one of your own objects to be its delegate.
This means every time Naurt updates certain properties, your delegate will
run some code
Properties
The Naurt Object has the following publicly available properties.
// Has Naurt been initialised? This will become true after init() has been called
// Unless this is true, nothing else can happen
public var isInitialised: Bool;
// Has Naurt been able to validate your API key? Unless this is true nothing else will happen
// Please contact support for help with your API key
public var isValidated: Bool;
// Is Naurt currently running and producing locations
public var isRunning: Bool;
// The most recently produced Naurt location
// Note this is an optional - when Naurt is not running or for a few ticks after being turned on,
// Naurt may not yet have a poisition
public var naurtPoint: NaurtLocation?;
// Naurt's generated UUID for this journey
public var journeyUuid: UUID? = nil;
// The tracking status
public var trackingStatus: NaurtTrackingStatus;
// You MUST use a delegate
public var delegate: NaurtDelegate!
Methods
The Naurt Object has the following publicly available methods.
Init
Init creates the Naurt object and also begins attempting validation
Warning
You must wait till Naurt is validated before using other methods
Signature
Naurt(apiKey: String)
Parameters
- apiKey: The API key assigned to you from Naurt.
Returns
Nothing is returned. Please use a delegate.
Delegate
After initialising Naurt, you must then attatch a
delegate before calling any other methods
Start
The start method begins a Naurt journey.
Signature
naurt.start(customMetaData: String? = nil) throws
Parameters
Optionally takes a customMetaData
of type String?
.
If no parameter is given, it defaults to nil
. The custom meta data
must be a valid JSON, and will be stored on the Naurt backend. This can be used
to assign, for example, your delivery IDs or driver IDs to a Naurt journey.
Returns
Nothing is returned. Please use a delegate.
Throws
Can throw a NaurtStartError
public enum StartNaurtError: Error {
case notInitialised // You must first initialise Naurt
case alreadyRunning // You may not start Naurt without first stopping it
case notValidated // Naurt must be valid to start
case invalidJson // customMetaData was not a valid JSON
}
Stop
The stop method ends a Naurt journey.
Note
When stopping, Naurt will attempt to upload any cached journeys. If this fails,
they will still remain cached until the next journey start/stop
Signature
naurt.stop() throws
Parameters
There are no parameters for this method.
Returns
Nothing is returned
Throws
Can throw a StopNaurtError
public enum StopNaurtError: Error {
case notRunning // You can not stop Naurt unless it is running
}
Warning
In order for journey data to reach Naurt's servers the stop method must be called.
Without calling this method, Naurt will not be able to provide further analytical data.
Types & Classes
Naurt exposes a few types & classes to the end developer.
Naurt Location
The NaurtLocation is a wrapper object around location information returned by the the SDK.
public struct NaurtLocation {
public var timestamp: Double // In UNIX seconds
public var latitude: Double
public var longitude: Double
public var altitude: Double // At the moment, this is simply passing through the iOS value
public var speed: Double
public var course: Double // In degrees, North is 0 and positive direction is clockwise i.e. compass format
public var horizontalAccuracy: Double
public var speedAccuracy: Double
public var courseAccuracy: Double
public var verticalAccuracy: Double // At the moment, this is simply passing through the iOS value
public var horizontalCovariance: Double
}
Naurt Tracking Status
This enum is used to indicate the current status of the Naurt object
public enum NaurtTrackingStatus{
case FULL // Naurt is fully operational, and operating at maximum performance
case READY // Naurt is ready to start
case UNKNOWN // An unknown error has occurred, please contact Naurt support
case AWAITING_VALIDATION // Naurt has been initialised and is now awaiting validation from the Naurt Server
case FAILING_VALIDATION // Naurt is faling validation. Check internet connection. Naurt will continue to try validating for you.
case INVALID_API_KEY // Your API key is invalid. Naurt will no longer try to validate. Please contact Naurt Support for help with your API Key
}
Naurt Delegate
You must make an object that conforms to the NaurtDelegate protocol
public protocol NaurtDelegate {
func didChangeInitialised(isInitialised: Bool);
func didChangeValidated(isValidated: Bool);
func didChangeRunning(isRunning: Bool);
func didUpdateLocation(naurtPoint: NaurtLocation?);
func didChangeJourneyUuid(journeyUuid: UUID?);
func didChangeStatus(trackingStatus: NaurtTrackingStatus);
func start();
func stop();
}
For example, to wrap Naurt into an observable object, use the following code
class NaurtDelegateObserver: ObservableObject, NaurtDelegate {
var naurt = Naurt(apiKey: "<YOUR API KEY HERE>");
@Published public var isInitialised = false;
@Published public var isValidated = false;
@Published public var isRunning = false;
@Published public var naurtLocation: NaurtLocation? = nil;
@Published public var journeyUuid: UUID? = nil;
@Published public var status: NaurtTrackingStatus = NaurtTrackingStatus.UNKNOWN;
init() {
// This is the most important line in the example
// You MUST do this or Naurt will crash!
naurt.delegate = self;
self.didChangeInitialised(isInitialised: self.naurt.isInitialised);
}
func didChangeInitialised(isInitialised: Bool) {
DispatchQueue.main.async {
self.isInitialised = isInitialised;
}
}
func didChangeValidated(isValidated: Bool) {
DispatchQueue.main.async {
self.isValidated = isValidated;
}
}
func didChangeRunning(isRunning: Bool) {
DispatchQueue.main.async {
self.isRunning = isRunning;
}
}
func didUpdateLocation(naurtPoint: NaurtLocation?) {
DispatchQueue.main.async {
self.naurtLocation = naurtPoint;
}
}
func didChangeJourneyUuid(journeyUuid: UUID?) {
DispatchQueue.main.async {
self.journeyUuid = journeyUuid;
}
}
func didChangeStatus(trackingStatus: NaurtTrackingStatus) {
DispatchQueue.main.async {
self.status = trackingStatus;
}
}
func start() {
// You will likely want a more extensive error handling
do {
try self.naurt.start();
} catch {
print(error);
}
}
func stop() {
do {
try self.naurt.stop();
} catch {
print(error);
}
}
}
Minimum Requirements
Naurt requires, at a minimum, the following hardware to function:
- 2GB of system RAM.
- Occasional internet connection (2G or equivalent).
- Minimum of 2 CPU cores (4 virtual cores / hyper threads ).
Recommended Requirements
Naurt functions best with the following hardware specification:
- 4GB of system RAM.
- Good available internet (3G or better).
- A Magnetometer / Compass with 3 axis data.
- An Accelerometer with 3 axis data.
- A Gyroscope with 3 axis data.
- 4 CPU cores ( 8 virtual cores / hyper threads ).
CPU Architectures
The Naurt SDK currently supports the following CPU architectures & instruction sets:
- arm64 (iPhones)
- x86_64 (simulator)
- M1 (simulator)
iOS API Level
Naurt requires iOS 13.