This page covers the high-level steps you follow to create customized guidance
as part of a [custom navigation
experience](https://developers.google.com/maps/documentation/navigation/ios-sdk/intro-custom-nav).
**This process differs from the process described in
[Navigate a
route](https://developers.google.com/maps/documentation/navigation/ios-sdk/route) as follows:**

- You first establish a navigation session independently and obtain a navigator instance through the session rather than by calling the view controller.
- You set up an event listener to respond to and manage navigation events.

1. **Create a navigation session** using
   [`GMSNavigationService.createNavigationSession`](https://developers.google.com/maps/documentation/navigation/ios-sdk/reference/objc/Classes/GMSNavigationServices.md.txt#+createnavigationsession)
   and begin navigation with a `setDestination` call. Where the Google
   navigation experience invokes the navigator through the navigation map view,
   the `GMSNavigationServices` controls and receives a stream of events from a
   navigation session *independently* from a UI instance. This means it can
   either run without a UI, or get passed to *any* UI-based experience. With
   this approach, the navigation session continues to run in your app until the
   last reference is removed from it.

2. **Establish a road-snapped location provider**. Use the location provider if
   you want your app to have continuous location monitoring, such as when
   displaying a navigation view with a blue dot along the route.

3. **Set up a listener for detailed turn-by-turn guidance** by implementing the
   `GMSNavigatorListener` protocol. Then, transform that information into
   whatever is needed for your custom navigation experience. For example:

   1. Implement text-only fields for simple screen casting of directions.
   2. Design and populate fields for your own UI.
4. **Set up a navigation simulator**. This is necessary for development and
   testing.

## Create an independent navigation session

The following code snippet from the demo shows navigation established
independently from the view controller. The code then adds an overview map
configured to show the current road-snapped location.

    // Create the navigation session.

     _navigationSession = [GMSNavigationServices createNavigationSession];
     GMSRoadSnappedLocationProvider *roadSnappedLocationProvider =
         _navigationSession.roadSnappedLocationProvider;
     [roadSnappedLocationProvider startUpdatingLocation];
     GMSNavigator *navigator = _navigationSession.navigator;
     [navigator addListener:self];
     navigator.voiceGuidance = GMSNavigationVoiceGuidanceSilent;
     navigator.sendsBackgroundNotifications = NO;
     _navigationSession.started = YES;
    ​​ [navigator setDestinations:@[ destination ]
                       callback:^(GMSRouteStatus routeStatus) {
                          // ...handle changes in route status.
                        }];

     // Add an overview map.
     _mapView = [[GMSMapView alloc] initWithFrame:CGRectZero];
     [self.mainStackView addArrangedSubview:_mapView];
     [self.mainStackView setNeedsLayout];
     _mapView.settings.compassButton = YES;
     _mapView.delegate = self;
     _mapView.myLocationEnabled = YES;
     _mapView.roadSnappedMyLocationSource = roadSnappedLocationProvider;

## Passing navigation from a custom experience to the Google experience

This code snippet illustrates how your app can allow the user to enter the
Google navigation experience from a custom navigation experience. This code
snippet also shows how your app makes this transition while sharing the map.

    `UIButton *button = [UIButton buttonWithType:UIButtonTypePlain`];

    [`button addTarget:self action:@selector(didTapEnterGoogleNavigationButton:)
    forControlState:[_directionsButton addTarget:self`];

    `...`

    [`_mapView enableNavigationWithSession:_navigationSession`];