Skip to content

08 Traffic information

Overview

In this tutorial, you will learn how to retrieve traffic information from the PTV Server.

Base

Use Tutorial07 as a starting point for this project.

Obtaining a key

For using the traffic information functionality in the sdk you will need an API key. Please contact the PTV Navigator product management to obtain such a key if you haven't already got one and set the key with [NSDK_Navigation setTrafficSearchWebConfiguration:token:] in the AppDelelgate application:didFinishLaunchingWithOptions: method.

@implementation AppDelegate

...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    ...

    // Uncomment the following line and replace <TOKEN> with your PTV Traffic Token if you want to use traffic
    //[NSDK_Navigation setTrafficSearchWebConfiguration:@"http://ti.ptvgroup.com/wfs" token:@"<TOKEN>" error:&error];

    ...
}

Retrieving traffic informations

To retrieve traffic informations we have to call [NSDK_Navigation searchTrafficInformationWithPosition:observer:error:] with the current GPS position. This will trigger an asynchronous call to a traffic REST service. For getting notified when the traffic request is finished we implement the NSDK_Observer protocol and pass self as the observer parameter. Because we want to fetch traffic updates repeatedly, we call it in the navigation loop every X times the loop is running.

@interface NavigationLoop : NSObject <NSDK_Observer>
@interface NavigationLoop () {
    BOOL _isNavigation;
    int loop;
}
...
@end


@implementation NavigationLoop

...

//NSDK_Observer protocol implementation
- (void) onFinished:(NSError*) error jobid:(int) job {
    if (error.code == 0) {

        dispatch_async(dispatch_get_main_queue(), ^{
            NSError *err;
            NSArray * arr = [NSDK_Navigation getTrafficSearchResults:&err];
            if (err == nil) {
                for (NSDK_TrafficSearchResult * trafficSearchResult in arr) {
                    NSLog(@"TrafficSearchResult: %@", [trafficSearchResult getDescription]);
                }
            }
        });
    } else {
        NSLog(@"NSDK_Observer finished with errorcode:%ld text:%@", (long)error.code, error.localizedDescription );
    }
}

- (void) _run {
  loop++;

  NSDK_GPSData * nsdk_gpsdata = [[NSDK_GPSManager sharedInstance] getCurrentPosition:nil];
  if (nsdk_gpsdata != nil && [nsdk_gpsdata getFix] >= 0) {
    ...
    if (loop % 10 == 0) {
        //fetch traffic information every 10th time we got a valid GPS Position
        loop = 0;
        NSError * err;
        [NSDK_Navigation searchTrafficInformationWithPosition:[nsdk_gpsdata getGPSPositionMerc] observer:self error:&err];
        if (err) {
            NSLog(@"searchTrafficInformationWithPosition called, error:%@", err);
        } else {
            NSLog(@"searchTrafficInformationWithPosition success");
        }
    }
  }

Attention

The call to [NSDK_Navigation searchTrafficInformationWithPosition:] returns immediately because it's asynchronous. Use the NSDK_Observer for obtaining the traffic incidents.

The NSDK_Observer implementation is used for getting traffic information if the previously triggered search has finished. This observer has one major function that we override: onFinished. (It has also a method onProgress, but we do not need this method in this chapter).

At this stage, we just log the traffic incidents.

At this stage, we just iterate through the traffic incidents and do a NSLog.

The request to the REST interface of the PTV Trafficserver only works, if you allow HTTP Requests in your Info.plist by defining the following keys/values:

  1. Define a key "App Transport Security Settings" with type "Dictionary" and
  2. "Allow Arbitrary Loads" with value "YES" as a member of this Dictionary.

In our Tutorial08 XCode Project, we have implemented a simple UIViewController (TrafficTableViewController) with a UITableView to display the traffic incidents. The TrafficTableViewController gets displayed, when a Button at the top of the ViewController is pressed.