Report a driver's route segment to a server

In this example, a driver is using turn-by-turn directions and we want to report the driver's route segment to a server when the driver first starts on a route, and any time the driver reroutes or otherwise starts on a new route.

You will need to provide your own server for this. The data in our example is sent to the server with a PUT request in JSON format. Modify the URL and other aspects of the URLRequest as necessary to suit your server.

Before you do this:

In order to see results, first make sure you have turn-by-turn navigation up and running in your app. If you haven't done this yet, here's how .

After you present the turn-by-turn UI, you can register to be notified whenever navigation starts a new route segment. (If you don't want to leave your desk to test this, it also works with our driving simulator , of course!)

NotificationCenter.default.addObserver(forName: NSNotification.Name.TGTelemetryInitialized, object: nil, queue: nil) { (notification) in
    guard let newRouteSegment = notification.userInfo?[TGTelemetryUserInfo.routeSegment] as? TGRouteSegment else {
        return
    }
    
    self.reportRouteSegment(newRouteSegment)
}
[NSNotificationCenter.defaultCenter addObserverForName:TGTelemetryInitializedNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull notification) {
    TGRouteSegment *newRouteSegment = notification.userInfo[TGTelemetryUserInfoRouteSegment];
    if (newRouteSegment == nil) {
        return;
    }
    
    [self reportRouteSegment:newRouteSegment];
}];

Once we've done that, we need some properties to keep track of our reporting.

// You can change these configuration values to suit your needs.
let reportRouteSegmentURL = URL(string: "http://localhost:3200/drivers/route_segment")!
let reportRouteSegmentMethod = "PUT"

// Keep track of when and what we last reported.
var lastReportedRouteSegment: TGRouteSegment?
// Put this inside your @interface
// Keep track of when and what we last reported.
@property (nonatomic, nullable) TGRouteSegment *lastReportedRouteSegment;

// Put these inside your @implementation
// You can change these configuration values to suit your needs.
static NSString *const reportRouteSegmentURL = @"http://localhost:3200/drivers/route_segment";
static NSString *const reportRouteSegmentMethod = @"PUT";

Now let's write the method to report our data to our server.

func reportRouteSegment(_ routeSegment: TGRouteSegment) {
    // Only report when the route segment changes
    guard routeSegment != lastReportedRouteSegment else {
        return
    }
    
    // Configure the request
    var request = URLRequest(url: reportRouteSegmentURL)
    request.httpMethod = reportRouteSegmentMethod
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    
    // Optional: send an ID for this session, so the server can tell different drivers apart
    //request.setValue(temporaryID, forHTTPHeaderField: "X-Temporary-ID")
    
    request.httpBody = try! JSONSerialization.data(withJSONObject: routeSegment.dictionary, options: [])
    
    // Send the request
    let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
        if let error = error {
            NSLog("Error reporting route segment: \(error)")
            
        } else {
            // Optionally, you can do something with the successful response here.
        }
    }
    task.resume()
    
    lastReportedRouteSegment = routeSegment
}
- (void)reportRouteSegment:(nonnull TGRouteSegment *)routeSegment {
    // Only report when the route segment changes
    if (self.lastReportedRouteSegment == routeSegment) {
        return;
    }
    
    // Configure the request
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:reportRouteSegmentURL]];
    request.HTTPMethod = reportRouteSegmentMethod;
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    
    // Optional: send an ID for this session, so the server can tell different drivers apart
    //[request setValue:self.temporaryID forHTTPHeaderField:@"X-Temporary-ID"];
    
    NSError *error = nil;
    NSData *encodedData = [NSJSONSerialization dataWithJSONObject:routeSegment.dictionary options:0 error:&error];
    if (encodedData != nil) {
        request.HTTPBody = encodedData;
        
    } else {
        @throw error;
    }
    
    // Send the request
    NSURLSessionDataTask *task = [NSURLSession.sharedSession dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        if (error != nil) {
            NSLog(@"Error reporting ETA: %@", error.userInfo);
            
        } else {
            // Optionally, you can do something with the successful response here.
        }
    }];
    [task resume];
    
    // Remember that we did this
    self.lastReportedRouteSegment = routeSegment;
}
Check out the iOS Reference App to see this example in action.

Look for example 403 in the app.