Overview
Radar’s trip tracking feature enables you to track journeys from origin to destination with real-time ETAs, status updates, and approaching/arrival events. Perfect for delivery, ride-sharing, and on-demand services.
Understanding Trips
A trip represents a journey to a destination geofence. Trips include:
External ID : Your unique identifier for the trip
Destination : A geofence tag or external ID
Metadata : Custom key-value pairs
Mode : Travel mode (car, bike, foot)
Status : Current trip state (started, approaching, arrived, etc.)
ETA : Real-time distance and duration to destination
Scheduled arrival : Optional expected arrival time
Multi-destination support : Multiple legs for complex routes
Trip Lifecycle
Trips progress through the following statuses:
Started
Trip has been created and tracking has begun. Status : RadarTripStatusStartedEvent : RadarEventTypeUserStartedTrip
Approaching
User is approaching the destination (within threshold). Status : RadarTripStatusApproachingEvent : RadarEventTypeUserApproachingTripDestination
Arrived
User has arrived at the destination geofence. Status : RadarTripStatusArrivedEvent : RadarEventTypeUserArrivedAtTripDestination
Completed or Canceled
Trip has been completed or canceled. Status : RadarTripStatusCompleted or RadarTripStatusCanceledEvent : RadarEventTypeUserStoppedTrip
Starting a Trip
Start a trip with destination geofence tag or external ID:
let tripOptions = RadarTripOptions (
externalId : "order-123" ,
destinationGeofenceTag : "store" ,
destinationGeofenceExternalId : "store-456"
)
tripOptions. mode = . car
tripOptions. metadata = [
"order_id" : "order-123" ,
"customer_name" : "John Doe"
]
Radar. startTrip ( options : tripOptions) { (status, trip, events) in
if status == .success {
print ( "Trip started: \( trip ? . _id ?? "" ) " )
print ( "ETA: \( trip ? . etaDuration ?? 0 ) minutes" )
print ( "Distance: \( trip ? . etaDistance ?? 0 ) meters" )
}
}
Either destinationGeofenceTag or destinationGeofenceExternalId is required. Both can be provided for additional matching.
Starting with Custom Tracking Options
You can specify custom tracking options for the trip duration:
let tripOptions = RadarTripOptions (
externalId : "trip-789" ,
destinationGeofenceTag : "restaurant" ,
destinationGeofenceExternalId : nil
)
let trackingOptions = RadarTrackingOptions. presetContinuous
trackingOptions. desiredMovingUpdateInterval = 30 // 30 seconds
Radar. startTrip (
options : tripOptions,
trackingOptions : trackingOptions
) { (status, trip, events) in
// handle response
}
When you start a trip, Radar automatically starts tracking if not already enabled. You can pass custom tracking options or set startTracking to false to manage tracking separately.
Trip Options Reference
Option Type Description externalIdStringYour unique identifier for the trip (required). destinationGeofenceTagString?Tag of the destination geofence. destinationGeofenceExternalIdString?External ID of the destination geofence. modeRadarRouteModeTravel mode: .car, .bike, .foot, .truck, .motorbike (default: .car). metadata[String: Any]?Custom key-value pairs for the trip. scheduledArrivalAtDate?Expected arrival time. approachingThresholdUInt16Distance threshold in meters for “approaching” status (default: 0, uses server default). startTrackingBOOLWhether to automatically start tracking (default: true). legs[RadarTripLeg]?Array of trip legs for multi-destination trips.
Updating a Trip
Manually update a trip’s options or status:
let tripOptions = RadarTripOptions (
externalId : "order-123" ,
destinationGeofenceTag : "store" ,
destinationGeofenceExternalId : "store-789"
)
tripOptions. metadata = [ "updated" : true ]
Radar. updateTrip (
options : tripOptions,
status : . unknown // or specify a status to update
) { (status, trip, events) in
if status == .success {
print ( "Trip updated" )
}
}
Pass RadarTripStatusUnknown to avoid updating the trip status when you only want to update other properties.
Completing a Trip
Mark a trip as completed:
Radar. completeTrip { (status, trip, events) in
if status == .success {
print ( "Trip completed" )
}
}
Canceling a Trip
Cancel an active trip:
Radar. cancelTrip { (status, trip, events) in
if status == .success {
print ( "Trip canceled" )
}
}
Completing or canceling a trip does not automatically stop tracking. Call Radar.stopTracking() if you want to stop location updates.
Getting Current Trip
Retrieve the current active trip:
if let trip = Radar. getTrip () {
print ( "Trip ID: \( trip. _id ) " )
print ( "External ID: \( trip. externalId ?? "" ) " )
print ( "Status: \( trip. status ) " )
print ( "ETA: \( trip. etaDuration ) minutes" )
print ( "Distance: \( trip. etaDistance ) meters" )
}
Trip Events
Receive trip events through the RadarDelegate:
func didReceiveEvents ( _ events : [RadarEvent], user : RadarUser ? ) {
for event in events {
switch event.type {
case . userStartedTrip :
print ( "Trip started" )
case . userUpdatedTrip :
if let trip = event.trip {
print ( "ETA: \( trip. etaDuration ) minutes" )
}
case . userApproachingTripDestination :
print ( "User is approaching destination" )
// Send notification to recipient
case . userArrivedAtTripDestination :
print ( "User arrived at destination" )
// Complete delivery, notify recipient
case . userStoppedTrip :
print ( "Trip stopped (completed or canceled)" )
default :
break
}
}
}
Multi-Destination Trips
For trips with multiple stops, use trip legs:
Creating Multi-Destination Trips
let leg1 = RadarTripLeg (
destinationGeofenceTag : "restaurant" ,
destinationGeofenceExternalId : "restaurant-123"
)
leg1. metadata = [ "order_id" : "order-1" ]
let leg2 = RadarTripLeg (
destinationGeofenceTag : "customer" ,
destinationGeofenceExternalId : "customer-456"
)
leg2. metadata = [ "order_id" : "order-2" ]
let tripOptions = RadarTripOptions (
externalId : "delivery-789" ,
destinationGeofenceTag : nil ,
destinationGeofenceExternalId : nil
)
tripOptions. legs = [leg1, leg2]
tripOptions. mode = . car
Radar. startTrip ( options : tripOptions) { (status, trip, events) in
if status == .success {
print ( "Multi-destination trip started" )
print ( "Legs: \( trip ? . legs ? . count ?? 0 ) " )
print ( "Current leg: \( trip ? . currentLegId ?? "" ) " )
}
}
Updating Trip Legs
Update the status of individual legs:
let trip = Radar. getTrip ()
if let legId = trip ? .legs ? . first ? ._id {
Radar. updateTripLeg (
legId : legId,
status : . arrived
) { (status, trip, leg, events) in
if status == .success {
print ( "Leg updated: \( leg ? . _id ?? "" ) " )
print ( "Leg status: \( leg ? . status ?? . unknown ) " )
}
}
}
Update Current Leg
Update the current active leg:
Radar. updateCurrentTripLeg ( status : . completed ) { (status, trip, leg, events) in
if status == .success {
print ( "Current leg completed" )
}
}
Reordering Trip Legs
Reorder legs in a multi-destination trip:
let trip = Radar. getTrip ()
if let legIds = trip ? .legs ? . map ({ $0 . _id }) {
let reorderedLegIds = [legIds[ 1 ], legIds[ 0 ]] // swap order
Radar. reorderTripLegs ( legIds : reorderedLegIds) { (status, trip, events) in
if status == .success {
print ( "Legs reordered" )
}
}
}
Trip Properties
Access trip properties from the RadarTrip object:
let trip = Radar. getTrip ()
// Identifiers
let radarId = trip ? . _id
let externalId = trip ? . externalId
// Status
let status = trip ? . status
// ETA information
let etaDuration = trip ? . etaDuration // minutes
let etaDistance = trip ? . etaDistance // meters
// Destination
let destinationTag = trip ? . destinationGeofenceTag
let destinationExternalId = trip ? . destinationGeofenceExternalId
let destinationLocation = trip ? . destinationLocation
// Metadata
if let metadata = trip ? .metadata {
print ( "Metadata: \( metadata ) " )
}
// Multi-destination trips
if let legs = trip ? .legs {
print ( "Number of legs: \( legs. count ) " )
let currentLegId = trip ? . currentLegId
}
Use Cases
Food Delivery Track delivery driver location and provide customers with real-time ETAs and approaching notifications.
Ride-Sharing Monitor driver progress to pickup location and notify passengers when the driver is approaching.
Package Delivery Track couriers across multiple delivery stops with multi-destination trip legs.
Field Services Track technicians traveling to service appointments with arrival notifications.
Best Practices
Use Unique External IDs
Use your own unique identifiers (order IDs, delivery IDs) as the trip’s external ID for easy reference.
Set Appropriate Travel Modes
Choose the correct travel mode (car, bike, foot) for accurate ETA calculations.
Include Rich Metadata
Store order details, customer information, and other context in trip metadata for personalization.
Handle Approaching Events
Listen for approaching events to send timely notifications to recipients.
Complete or Cancel Trips
Always complete or cancel trips when finished to maintain clean trip state.