> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/radarlabs/radar-sdk-ios/llms.txt
> Use this file to discover all available pages before exploring further.

# RadarTripLeg

> Represents a leg of a multi-destination trip in the Radar iOS SDK

`RadarTripLeg` represents a single destination within a multi-destination trip. Each leg can have its own destination (geofence, address, or coordinates), status, ETA, and metadata. Trip legs allow you to track progress through a route with multiple stops.

## Initializers

### initWithDestinationGeofenceTag:destinationGeofenceExternalId:

```swift theme={null}
init(destinationGeofenceTag: String?, 
     destinationGeofenceExternalId: String?)
```

```objective-c theme={null}
- (instancetype)initWithDestinationGeofenceTag:(NSString *_Nullable)destinationGeofenceTag
                 destinationGeofenceExternalId:(NSString *_Nullable)destinationGeofenceExternalId;
```

Initializes a trip leg with a destination geofence identified by tag and external ID.

<ParamField path="destinationGeofenceTag" type="String" optional>
  The tag of the destination geofence.
</ParamField>

<ParamField path="destinationGeofenceExternalId" type="String" optional>
  The external ID of the destination geofence.
</ParamField>

### initWithDestinationGeofenceId:

```swift theme={null}
init(destinationGeofenceId: String)
```

```objective-c theme={null}
- (instancetype)initWithDestinationGeofenceId:(NSString *_Nonnull)destinationGeofenceId;
```

Initializes a trip leg with a destination geofence identified by its Radar ID.

<ParamField path="destinationGeofenceId" type="String" required>
  The Radar ID of the destination geofence.
</ParamField>

### initWithAddress:

```swift theme={null}
init(address: String)
```

```objective-c theme={null}
- (instancetype)initWithAddress:(NSString *_Nonnull)address;
```

Initializes a trip leg with an address destination.

<ParamField path="address" type="String" required>
  The address string for the destination.
</ParamField>

### initWithCoordinates:

```swift theme={null}
init(coordinates: CLLocationCoordinate2D)
```

```objective-c theme={null}
- (instancetype)initWithCoordinates:(CLLocationCoordinate2D)coordinates;
```

Initializes a trip leg with coordinate-based destination.

<ParamField path="coordinates" type="CLLocationCoordinate2D" required>
  The coordinates for the destination (latitude and longitude).
</ParamField>

## Response Properties

These properties are populated from server responses and are read-only.

<ResponseField name="_id" type="String" readonly optional>
  The Radar ID of the leg. Set from server response. Use this ID when calling `updateTripLeg` or `completeTripLeg`.
</ResponseField>

<ResponseField name="status" type="RadarTripLegStatus" readonly>
  The status of the leg. Set from server response.

  **Values:**

  * `RadarTripLegStatusUnknown` - Unknown status
  * `RadarTripLegStatusPending` - Leg is queued but not yet active
  * `RadarTripLegStatusStarted` - Device is traveling to this leg's destination
  * `RadarTripLegStatusApproaching` - Device is approaching the destination
  * `RadarTripLegStatusArrived` - Device has arrived at the destination
  * `RadarTripLegStatusCompleted` - Leg has been completed
  * `RadarTripLegStatusCanceled` - Leg has been canceled
  * `RadarTripLegStatusExpired` - Leg has expired
</ResponseField>

<ResponseField name="destinationType" type="RadarTripLegDestinationType" readonly>
  The destination type for this leg. When parsed from a server response, reflects the server's `destination.type`. Otherwise, inferred from which properties are set (geofence > address > coordinates).

  **Values:**

  * `RadarTripLegDestinationTypeUnknown` - Unknown destination type
  * `RadarTripLegDestinationTypeGeofence` - Destination is a geofence
  * `RadarTripLegDestinationTypeAddress` - Destination is an address
  * `RadarTripLegDestinationTypeCoordinates` - Destination is a coordinate pair
</ResponseField>

<ResponseField name="createdAt" type="NSDate" readonly optional>
  The date when the leg was created. Set from server response.
</ResponseField>

<ResponseField name="updatedAt" type="NSDate" readonly optional>
  The date when the leg was last updated. Set from server response.
</ResponseField>

<ResponseField name="etaDuration" type="float" readonly>
  The ETA duration in minutes to this leg's destination. Set from server response.
</ResponseField>

<ResponseField name="etaDistance" type="float" readonly>
  The ETA distance in meters to this leg's destination. Set from server response.
</ResponseField>

## Geofence Destination Properties

<ResponseField name="destinationGeofenceTag" type="String" optional>
  The tag of the destination geofence for this leg. Use with `destinationGeofenceExternalId` for geofence-based destinations.
</ResponseField>

<ResponseField name="destinationGeofenceExternalId" type="String" optional>
  The external ID of the destination geofence for this leg. Use with `destinationGeofenceTag` for geofence-based destinations.
</ResponseField>

<ResponseField name="destinationGeofenceId" type="String" optional>
  The Radar ID of the destination geofence for this leg. Alternative to using `destinationGeofenceTag` + `destinationGeofenceExternalId`.
</ResponseField>

## Address Destination Properties

<ResponseField name="address" type="String" optional>
  The address string for the destination of this leg. Use for address-based destinations.
</ResponseField>

## Coordinate Destination Properties

<ResponseField name="coordinates" type="CLLocationCoordinate2D">
  The coordinates for the destination of this leg. Use for coordinate-based destinations. Set latitude and longitude.
</ResponseField>

<ResponseField name="hasCoordinates" type="BOOL" readonly>
  Whether coordinates have been explicitly set and are valid.
</ResponseField>

<ResponseField name="arrivalRadius" type="NSInteger">
  The arrival radius in meters for coordinate-based destinations. Only used when coordinates are set. Defines how close the device needs to be to the coordinates to be considered arrived.
</ResponseField>

## Common Properties

<ResponseField name="stopDuration" type="NSInteger">
  The stop duration in minutes for this leg. Indicates how long the device should remain at this destination before moving to the next leg.
</ResponseField>

<ResponseField name="metadata" type="NSDictionary" optional>
  An optional set of custom key-value pairs for this leg. Use this to attach any custom data to the leg.
</ResponseField>

## Class Methods

### legFromDictionary

```swift theme={null}
class func leg(from dictionary: [AnyHashable : Any]?) -> RadarTripLeg?
```

```objective-c theme={null}
+ (RadarTripLeg *_Nullable)legFromDictionary:(NSDictionary *_Nullable)dict;
```

Creates a `RadarTripLeg` from a dictionary representation.

<ParamField path="dict" type="NSDictionary" optional>
  The dictionary containing leg data.
</ParamField>

**Returns:** A `RadarTripLeg` instance, or `nil` if the dictionary is invalid.

### legsFromArray

```swift theme={null}
class func legs(from array: [Any]?) -> [RadarTripLeg]?
```

```objective-c theme={null}
+ (NSArray<RadarTripLeg *> *_Nullable)legsFromArray:(NSArray *_Nullable)array;
```

Creates an array of `RadarTripLeg` objects from an array of dictionaries.

<ParamField path="array" type="NSArray" optional>
  The array of dictionaries containing leg data.
</ParamField>

**Returns:** An array of `RadarTripLeg` instances, or `nil` if the array is invalid.

### arrayForLegs

```swift theme={null}
class func array(for legs: [RadarTripLeg]?) -> [[AnyHashable : Any]]?
```

```objective-c theme={null}
+ (NSArray<NSDictionary *> *_Nullable)arrayForLegs:(NSArray<RadarTripLeg *> *_Nullable)legs;
```

Converts an array of legs to an array of dictionaries.

<ParamField path="legs" type="NSArray<RadarTripLeg *>" optional>
  The array of `RadarTripLeg` instances.
</ParamField>

**Returns:** An array of dictionary representations.

### stringForStatus

```swift theme={null}
class func string(for status: RadarTripLegStatus) -> String
```

```objective-c theme={null}
+ (NSString *)stringForStatus:(RadarTripLegStatus)status;
```

Returns the string representation of a trip leg status.

### statusForString

```swift theme={null}
class func status(for string: String) -> RadarTripLegStatus
```

```objective-c theme={null}
+ (RadarTripLegStatus)statusForString:(NSString *)string;
```

Returns the trip leg status for a string representation.

### stringForDestinationType

```swift theme={null}
class func string(forDestinationType destinationType: RadarTripLegDestinationType) -> String
```

```objective-c theme={null}
+ (NSString *)stringForDestinationType:(RadarTripLegDestinationType)destinationType;
```

Returns the string representation of a trip leg destination type.

### destinationTypeForString

```swift theme={null}
class func destinationType(for string: String) -> RadarTripLegDestinationType
```

```objective-c theme={null}
+ (RadarTripLegDestinationType)destinationTypeForString:(NSString *)string;
```

Returns the trip leg destination type for a string representation.

## Instance Methods

### dictionaryValue

```swift theme={null}
func dictionaryValue() -> [AnyHashable : Any]
```

```objective-c theme={null}
- (NSDictionary *)dictionaryValue;
```

Converts the leg to a dictionary representation for API serialization.

**Returns:** A dictionary representation of the leg.

## Usage Examples

### Creating Trip Legs with Different Destination Types

```swift theme={null}
// Geofence destination
let leg1 = RadarTripLeg(
    destinationGeofenceTag: "store",
    destinationGeofenceExternalId: "store-123"
)
leg1.stopDuration = 15 // 15 minutes
leg1.metadata = ["orderId": "abc123"]

// Address destination
let leg2 = RadarTripLeg(address: "123 Main St, San Francisco, CA")
leg2.stopDuration = 10

// Coordinate destination
let leg3 = RadarTripLeg(
    coordinates: CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194)
)
leg3.arrivalRadius = 100 // 100 meters
leg3.stopDuration = 20
```

```objective-c theme={null}
// Geofence destination
RadarTripLeg *leg1 = [[RadarTripLeg alloc]
    initWithDestinationGeofenceTag:@"store"
    destinationGeofenceExternalId:@"store-123"];
leg1.stopDuration = 15; // 15 minutes
leg1.metadata = @{@"orderId": @"abc123"};

// Address destination
RadarTripLeg *leg2 = [[RadarTripLeg alloc]
    initWithAddress:@"123 Main St, San Francisco, CA"];
leg2.stopDuration = 10;

// Coordinate destination
RadarTripLeg *leg3 = [[RadarTripLeg alloc]
    initWithCoordinates:CLLocationCoordinate2DMake(37.7749, -122.4194)];
leg3.arrivalRadius = 100; // 100 meters
leg3.stopDuration = 20;
```

### Creating a Multi-Stop Route

```swift theme={null}
// Create multiple legs for a delivery route
let legs = [
    RadarTripLeg(
        destinationGeofenceTag: "customer",
        destinationGeofenceExternalId: "customer-1"
    ),
    RadarTripLeg(
        destinationGeofenceTag: "customer",
        destinationGeofenceExternalId: "customer-2"
    ),
    RadarTripLeg(
        destinationGeofenceTag: "customer",
        destinationGeofenceExternalId: "customer-3"
    )
]

// Set stop duration for each leg
legs.forEach { $0.stopDuration = 5 }

// Create trip options with legs
let tripOptions = RadarTripOptions(
    externalId: "delivery-route-456",
    destinationGeofenceTag: nil,
    destinationGeofenceExternalId: nil
)
tripOptions.legs = legs
tripOptions.mode = .car

Radar.startTrip(options: tripOptions)
```

```objective-c theme={null}
// Create multiple legs for a delivery route
NSArray<RadarTripLeg *> *legs = @[
    [[RadarTripLeg alloc]
        initWithDestinationGeofenceTag:@"customer"
        destinationGeofenceExternalId:@"customer-1"],
    [[RadarTripLeg alloc]
        initWithDestinationGeofenceTag:@"customer"
        destinationGeofenceExternalId:@"customer-2"],
    [[RadarTripLeg alloc]
        initWithDestinationGeofenceTag:@"customer"
        destinationGeofenceExternalId:@"customer-3"]
];

// Set stop duration for each leg
for (RadarTripLeg *leg in legs) {
    leg.stopDuration = 5;
}

// Create trip options with legs
RadarTripOptions *tripOptions = [[RadarTripOptions alloc]
    initWithExternalId:@"delivery-route-456"
    destinationGeofenceTag:nil
    destinationGeofenceExternalId:nil];
tripOptions.legs = legs;
tripOptions.mode = RadarRouteModeCar;

[Radar startTripWithOptions:tripOptions];
```

### Monitoring Leg Progress

```swift theme={null}
Radar.getLocation { (status, location, user, events) in
    guard let trip = user?.trip, let legs = trip.legs else { return }
    
    for (index, leg) in legs.enumerated() {
        print("Leg \(index + 1): \(RadarTripLeg.string(for: leg.status))")
        
        // Check if this is the current active leg
        if leg._id == trip.currentLegId {
            print("  Current leg - ETA: \(leg.etaDuration) min, Distance: \(leg.etaDistance) m")
            
            switch leg.status {
            case .started:
                print("  En route to destination")
            case .approaching:
                print("  Approaching destination")
            case .arrived:
                print("  Arrived! Completing leg...")
                if let legId = leg._id {
                    Radar.completeTripLeg(legId: legId)
                }
            case .completed:
                print("  Leg completed")
            default:
                break
            }
        }
    }
}
```

```objective-c theme={null}
[Radar getLocationWithCompletionHandler:^(RadarStatus status, CLLocation *location, RadarUser *user, NSArray<RadarEvent *> *events) {
    if (!user.trip || !user.trip.legs) {
        return;
    }
    
    for (NSInteger i = 0; i < user.trip.legs.count; i++) {
        RadarTripLeg *leg = user.trip.legs[i];
        NSLog(@"Leg %ld: %@", (long)(i + 1), [RadarTripLeg stringForStatus:leg.status]);
        
        // Check if this is the current active leg
        if ([leg._id isEqualToString:user.trip.currentLegId]) {
            NSLog(@"  Current leg - ETA: %.1f min, Distance: %.1f m", leg.etaDuration, leg.etaDistance);
            
            switch (leg.status) {
                case RadarTripLegStatusStarted:
                    NSLog(@"  En route to destination");
                    break;
                case RadarTripLegStatusApproaching:
                    NSLog(@"  Approaching destination");
                    break;
                case RadarTripLegStatusArrived:
                    NSLog(@"  Arrived! Completing leg...");
                    if (leg._id) {
                        [Radar completeTripLegWithLegId:leg._id];
                    }
                    break;
                case RadarTripLegStatusCompleted:
                    NSLog(@"  Leg completed");
                    break;
                default:
                    break;
            }
        }
    }
}];
```

### Updating a Trip Leg

```swift theme={null}
// Update leg metadata or properties
if let currentLegId = user?.trip?.currentLegId {
    let updatedMetadata = ["status": "delayed", "reason": "traffic"]
    Radar.updateTripLeg(
        legId: currentLegId,
        metadata: updatedMetadata
    ) { (status, user, events) in
        if status == .success {
            print("Leg updated successfully")
        }
    }
}
```

```objective-c theme={null}
// Update leg metadata or properties
if (user.trip.currentLegId) {
    NSDictionary *updatedMetadata = @{@"status": @"delayed", @"reason": @"traffic"};
    [Radar updateTripLegWithLegId:user.trip.currentLegId
                          metadata:updatedMetadata
                 completionHandler:^(RadarStatus status, RadarUser *user, NSArray<RadarEvent *> *events) {
        if (status == RadarStatusSuccess) {
            NSLog(@"Leg updated successfully");
        }
    }];
}
```

## Related

* [RadarTripOptions](/api/radar-trip-options) - Configure trips with multiple legs
* [RadarTrip](/api/radar-trip) - The parent trip object containing legs
* [Trip Tracking Guide](https://radar.com/documentation/trip-tracking) - Complete guide to trip tracking
