Naurt iOS SDK Last updated: 24-10-2022

Naurt's iOS SDK is a development kit that integrates our technology into your iOS apps.

If you'd like to enhance location fixes during dynamic journeys on iOS, this product is the one for you.

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.

Naurt Drift Example


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

Installation

A walk through of how to introduce Naurt to your project.

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

Dependencies for XCode project

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).

Dependencies for XCode project

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

Importing Framework in XCode

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

Importing Framework in XCode

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

Importing Framework in XCode

Integration

The Naurt Object

Naurt can be imported by using the following import

import NaurtSDK

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);
                }
                
            } 
        }
    

Supported Devices

What's supported by Naurt, and what isn't.

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.