Skip to content

iOS SmartDrive framework

YuliyaArtsiomchykScope edited this page Jul 13, 2026 · 13 revisions

SmartDrive SDK Documentation - v1.1.5 (13 Jul, 2025)

This document describes how ScopeTechnology framework "SmartDrive" works and how to integrate into your application. While the target audience is coders/developers, it brings better understanding for those who are not too tech-savvy as well.

SmartDrive framework main functionality is to record trips. It supports trip recording:

  • with Beacons (BLE device from ScopeTechnology).
  • with MHub837s (BLE device from ScopeTechnology).
  • without any BLE device (called "Smart" version).

Table of contents

1. Installation Guide

Following instructions will allow you to integrate our SDK into your application. Additionally, here is the demo sample app that you can follow while going through this document.

1.1. Overview

In introduction we mentioned that SmartDrive has two configuration types:

  • for BLE devices (including ScopeTechnology - beacons and MHubs837s)
  • for no BLE devices (smart solution)

It is important to apply correct configuration and permissions for your specific business needs.

1.2. Requirements

  • Minimum Deployments: iOS 11.0

Permissions:

  • Location permissions. Mandatory permissions for "BLE device" (beacons/mhubs) and "no BLE device" (smart version) support. Location permissions are used for getting location data that allows us to draw trip route and analyze trip in details, it also is needed for BLE device scanning.
CLLocationManager.locationServicesEnabled() == true
CLLocationManager.authorizationStatus() == .authorizedAlways

Tip

request location permission from the app

  • Motion and Fitness permission. Mandatory permission for "BLE device" (beacons/mhubs) and "no BLE device" (smart version) support. In smart version it allows our algorithm to understand weather the user is in a car (so we can detect trip in timely manner) or is taking a walk (to avoid ghost trips). In all the versions it's also used for so called exception detection (driving behaviour during the trip).
CMMotionActivityManager.authorizationStatus() == .authorized

Tip

request Motion and Fitness permission from the app

1.3. Integration

The library (SDK) is shared within SmartDriveDemo app as .xcframework

Step 1. Request the latest version of SmartDriveDemo app as .zip

Step 2. Copy SCPSmartDrive.xcframework from root directory to your project as regular framework

Important

Always confirm that you are using latest version.

2. SmartDrive Initialization

2.1 Configuration

2.1.1. Initial Configuration

All core configuration happens using SCPSmartDriveManager helper class.

import SCPSmartDrive

2.1.2 Record Only - Beacon Trips / Smart Trips

We need to tell SmartDrive framework weather we want to use BLE devices for trip recording or use smart solution instead.

Important

If SmartDrive is intended to work with BLE devices

UserDefaults.standard.set(true, forKey: "recordTripsWithBeaconOnly")
SCPSmartDriveManager.sharedInstance().setMotionActivityEnabled(false)
SCPSmartDriveManager.sharedInstance().setSBeaconManagerEnabled(true)
SCPSmartDriveManager.sharedInstance().startSignificantLocationUpdates(true)
SCPSmartDriveManager.sharedInstance().setTripMonitoringDisabled(false)

Important

If SmartDrive is intended to work with no BLE devices using smart solution

UserDefaults.standard.set(false, forKey: "recordTripsWithBeaconOnly")
SCPSmartDriveManager.sharedInstance().setMotionActivityEnabled(true)
SCPSmartDriveManager.sharedInstance().setSBeaconManagerEnabled(false)
SCPSmartDriveManager.sharedInstance().setTripAutostartEnabled(true)
SCPSmartDriveManager.sharedInstance().setTripMonitoringDisabled(false)

2.1.3. Auto Sending

Trip auto sending happens automatically, no additional code needed.

2.1.4. End Trip Timer

Our solution uses trip end timer to validate if trip has truly finished (compared to heavy traffic with no movement for longer period of time). Trip end timer does not change recorded trip actual time range.

Warning

While you can change trip end timer based on your needs, it is strongly suggested to configure it between 3 - 5 minutes range to avoid ghost trips. Default value is 300 seconds.

UserDefaults.standard.set(300, forKey: "kSettingsTripEndThreshold") //Example for 5 minutes

2.1.5. Mode of Transport (MOT)

Mode of Transport is clever solution to avoid trip recording on pre-defined transport types. For instance, if you want to avoid public transport buses or trains, you can configure so and framework will discard them. By default - disabled.

let motSkipTrip = [
    "Air", // Airplane
    "Water", // Boats, jet skis
    "Public", // Bus, trams etc.
    "Railway", // Train
    "OffRoad" // OffRoad. Available from v1.1.9
]

SCPSmartDriveManager.sharedInstance().configureMOT(withIsMOTEnabled: true,
                                                            motSkipTrip: motSkipTrip,
                                                            elevationKey: "",
                                                            staticMapsKey: "<YOUR_KEY_HERE>")

2.1.6. Distracted Driving

When enabled will monitor driver actions during the trip. Following distracting driving types are available:

  • PHONE USE - phone is being used while driving. Browsing different apps, tilting it, shaking it and other similar actions will be caught.
  • PHONE CALLS - phone call is while driving WITH OUT headset (not available in current version).
SCPSmartDriveManager.sharedInstance().setDistractedDriverDetectionEnabled(true)

// set distraction types which should be tracked
SCPSmartDriveManager.sharedInstance().getDistractedDriverManager()?.setPhoneUseDetectionEnabled(true)
SCPSmartDriveManager.sharedInstance().getDistractedDriverManager()?.setPhoneCallDetectionEnabled(true)

Tip

If you want to detect events based on minimum speed, make sure you are using library version v1.0.21+

SCPSmartDriveManager.sharedInstance().getDistractedDriverManager()?.setMinimumSpeedToDetectDistraction(5) // If user speed is below 5km/h -> ignore events

3. Trip Recording

3.1 Start SmartDrive

SmartDrive is started as user logs in and above mentioned configuration methods are called.

3.2. Stop SmartDrive

Stop SmartDrive manually on logout to prevent trip recording for unauthorised user:

SCPSmartDriveManager.sharedInstance().setTripDataMonitoringOn(false)
SCPSmartDriveManager.sharedInstance().setTripMonitoringDisabled(true)
SCPSmartDriveManager.sharedInstance().setMotionActivityEnabled(false)
SCPSmartDriveManager.sharedInstance().setDistractedDriverDetectionEnabled(false)

// If SmartDrive is intended to work **with BLE devices**
SCPSmartDriveManager.sharedInstance().startSignificantLocationUpdates(false)

// If SmartDrive is intended to work **with no BLE devices** using smart solution
SCPSmartDriveManager.sharedInstance().setTripAutostartEnabled(false)

3.3. Realtime trip events sending

When configured lets send events during the trip. Trip start, end and periodic location updates trigger all the unsent events sending. Configuration:

// Set sending enabled first:
AppDelegate.shared.isRealtimeTripSendingEnabled = true

// Provide MProfiler credentials: service url, service provider, api key:
let mProfilerServiceUrl = "<YOUR_VALUE>"
let mProfilerServiceProvider = "<YOUR_VALUE>"
let mProfilerApiKey = "<YOUR_VALUE>"
SCPSmartDriveManager.sharedInstance()?.configureMProfilerEnvironment(mProfilerServiceUrl, provider: mProfilerServiceProvider, key: mProfilerApiKey) { error in
    // Check an error here
}

// If needed it's possible to check if MProfiler is configured correctly:
SCPSmartDriveManager.sharedInstance()?.checkMProfilerConfiguration { isValid, message in
    // Check isValid  
}

// Observe for a new event and send events when start, end or periodic location updates event has been received:
NotificationCenter.default.addObserver(self, selector: #selector(didReceiveNewEvent(_:)), name: NSNotification.Name.newEventRegistration, object: nil)
...
@objc private func didReceiveNewEvent(_ notification: NSNotification) {
    guard let event = notification.userInfo?["event"] as? SCPEvent else {
        return
    }
    if event.eventType == NSNumber(integerLiteral: Int(SCPEventType.tripStart.rawValue)) || event.eventType == NSNumber(integerLiteral: Int(SCPEventType.tripEnd.rawValue)) || event.eventType == NSNumber(integerLiteral: Int(SCPEventType.periodicLocationUpdate.rawValue)) {
        sendEvents()
    }
}
...
private func sendEvents() {
    // See implementation in SmartDriveDemo app
}

3.4. Session persistence and app lifecycle

The SDK persists the session for you — SDApiManager.isAuthorized() returns true on the next launch, so you should check it at launch and arm the SDK from didFinishLaunchingWithOptions rather than forcing a re-login. Turning the screen off suspends the app (it does not end the session); only a real termination re-runs launch, and that path reuses the persisted session.

Important

If users are sent back to the login screen after locking the phone or reopening the app, it is almost always the application clearing or ignoring the persisted session — not the SDK.

See iOS Session & App Lifecycle Management for the full lifecycle contract, code for each event, common mistakes, and a verification checklist.

Clone this wiki locally