Skip to main content
The Radar iOS SDK supports indoor positioning to track users inside buildings with floor-level accuracy. This is achieved through indoor scanning and pressure sensor integration.

Overview

Indoor positioning features:
  • Floor level detection: Use barometric pressure to determine which floor the user is on
  • Indoor scanning: Integrate with third-party indoor positioning systems
  • Beacon ranging: Track proximity to iBeacons for precise indoor location
  • Altitude tracking: Monitor relative and absolute altitude changes

Enable indoor scanning

To enable indoor scanning, set the useIndoorScan property on your tracking options:
import RadarSDK

let trackingOptions = RadarTrackingOptions()
trackingOptions.useIndoorScan = true

Radar.startTracking(trackingOptions: trackingOptions)
Indoor scanning requires configuration on the Radar dashboard and integration with a supported indoor positioning provider.

Indoor positioning protocol

The SDK provides a protocol for integrating custom indoor positioning systems:
import CoreLocation
import RadarSDK

@objc protocol RadarIndoorsProtocol: NSObjectProtocol {
    @objc static func startIndoorScan(
        _ geofenceId: String,
        forLength scanLengthSeconds: Int32,
        withKnownLocation knownLocation: CLLocation?,
        completionHandler: @escaping RadarIndoorsScanCompletionHandler
    )
}
The completion handler returns:
  • A scan result string with positioning data
  • The device’s location at the start of the scan

Floor level detection

Enable pressure sensor integration to detect floor changes:
let trackingOptions = RadarTrackingOptions()
trackingOptions.usePressure = true
trackingOptions.useMotion = true // Required for pressure sensor access

Radar.startTracking(trackingOptions: trackingOptions)
Pressure sensor data requires:
  • The RadarSDKMotion framework to be integrated
  • Motion & Fitness permissions to be granted
  • A device with a barometer (iPhone 6 and later)

Beacon-based indoor positioning

Use iBeacons for precise indoor location tracking:
1

Enable beacon monitoring

let trackingOptions = RadarTrackingOptions()
trackingOptions.beacons = true

Radar.startTracking(trackingOptions: trackingOptions)
2

Track with beacon ranging

When calling trackOnce, enable beacon ranging:
Radar.trackOnce(desiredAccuracy: .high, beacons: true) { status, location, events, user in
    if status == .success {
        print("Tracked with beacons")
    }
}
3

Configure beacons in the dashboard

Set up your iBeacon UUIDs, majors, and minors in the Radar dashboard under the Beacons section.

Altitude tracking

The SDK tracks altitude using both relative and absolute altitude data:

Relative altitude (pressure-based)

Uses the device’s barometer to measure changes in altitude:
// Automatically enabled when usePressure = true
trackingOptions.usePressure = true
Relative altitude provides:
  • Altitude change in meters from a reference point
  • Barometric pressure in kilopascals (kPa)

Absolute altitude (iOS 15+)

On iOS 15 and later, the SDK also uses absolute altitude data:
// Automatically enabled when available (iOS 15+)
if #available(iOS 15.0, *) {
    // CMAbsoluteAltitudeData is used automatically
}
Absolute altitude provides:
  • Altitude above sea level in meters
  • Accuracy of the altitude measurement
  • Precision of the altitude data

Indoor scan workflow

When indoor scanning is enabled, the SDK follows this workflow:
  1. User enters a configured geofence
  2. SDK checks if indoor scanning is enabled for that geofence
  3. Indoor scan is triggered automatically
  4. Scan results are sent to the Radar API with location data
  5. Indoor positioning data is returned in the track response
// Indoor scanning happens automatically when configured
let trackingOptions = RadarTrackingOptions()
trackingOptions.useIndoorScan = true
trackingOptions.syncGeofences = true // Sync nearby geofences

Radar.startTracking(trackingOptions: trackingOptions)

Combining indoor positioning methods

For best results, combine multiple indoor positioning methods:
let trackingOptions = RadarTrackingOptions()

// Enable all indoor positioning features
trackingOptions.beacons = true
trackingOptions.useIndoorScan = true
trackingOptions.usePressure = true
trackingOptions.useMotion = true
trackingOptions.syncGeofences = true

Radar.startTracking(trackingOptions: trackingOptions)

Best practices

Test in real environments

Test indoor positioning in actual buildings with multiple floors to verify accuracy.

Calibrate beacons

Ensure beacons are properly positioned and configured in the Radar dashboard.

Monitor permission status

Check that Motion & Fitness and Bluetooth permissions are granted for full functionality.

Combine with outdoor tracking

Seamlessly transition between indoor and outdoor positioning.

Receive indoor location updates

Receive indoor positioning data through the delegate:
import RadarSDK

class MyRadarDelegate: NSObject, RadarDelegate {
    func didUpdateLocation(_ location: CLLocation, user: RadarUser) {
        // Check for beacon proximity
        if let beacons = user.beacons, !beacons.isEmpty {
            print("Near \(beacons.count) beacon(s)")
        }
        
        // Check altitude data
        if let altitude = location.altitude {
            print("Altitude: \(altitude) meters")
        }
    }
}

Radar.setDelegate(MyRadarDelegate())

Troubleshooting

  • Verify the device has a barometer (iPhone 6 and later)
  • Ensure both useMotion and usePressure are set to true
  • Check that Motion & Fitness permissions are granted
  • Verify the RadarSDKMotion framework is integrated
  • Verify Bluetooth is enabled on the device
  • Check that beacons is set to true in tracking options
  • Ensure beacons are configured in the Radar dashboard
  • Test beacon ranging with a known beacon nearby
  • Verify useIndoorScan is enabled
  • Check that indoor scanning is configured for your geofences in the dashboard
  • Ensure the device is within a configured geofence
  • Check that syncGeofences is enabled to receive geofence data