Sigue esta guía para trazar una ruta dentro de tu app a un solo destino con el SDK de Navigation para iOS.
Descripción general
- Integra el SDK de Navigation en tu app, como se describe en la sección Configura tu proyecto.
- Configura un
GMSMapView
. - Pídele al usuario que acepte los Términos y Condiciones, y que autorice los servicios de ubicación y las notificaciones en segundo plano.
- Crea un array que contenga uno o más destinos.
Define un
GMSNavigator
para controlar la navegación paso a paso.- Agrega destinos con
setDestinations
. - Establece
isGuidanceActive
entrue
para iniciar la navegación. - Usa
simulateLocationsAlongExistingRoute
para simular el progreso del vehículo a lo largo de la ruta, para probar, depurar y demostrar tu app.
- Agrega destinos con
Consulta el código
Mostrar/ocultar el código Swift del controlador de vista de navegación
/* * Copyright 2017 Google Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import GoogleNavigation import UIKit class ViewController: UIViewController { var mapView: GMSMapView! var locationManager: CLLocationManager! override func loadView() { locationManager = CLLocationManager() // Set up the map view. let camera = GMSCameraPosition.camera(withLatitude: 47.67, longitude: -122.20, zoom: 14) mapView = GMSMapView.map(withFrame: .zero, camera: camera) // Show the terms and conditions. let companyName = "Ride Sharing Co." GMSNavigationServices.showTermsAndConditionsDialogIfNeeded( withCompanyName: companyName ) { termsAccepted in if termsAccepted { // Enable navigation if the user accepts the terms. self.mapView.isNavigationEnabled = true self.mapView.settings.compassButton = true // Request authorization to use location services. self.locationManager.requestAlwaysAuthorization() // Request authorization for alert notifications which deliver guidance instructions // in the background. UNUserNotificationCenter.current().requestAuthorization(options: [.alert]) { granted, error in // Handle denied authorization to display notifications. if !granted || error != nil { print("User rejected request to display notifications.") } } } else { // Handle rejection of terms and conditions. } } view = mapView makeButton() } // Create a route and start guidance. func startNav() { var destinations = [GMSNavigationWaypoint]() destinations.append( GMSNavigationWaypoint.init( placeID: "ChIJnUYTpNASkFQR_gSty5kyoUk", title: "PCC Natural Market")!) destinations.append( GMSNavigationWaypoint.init( placeID: "ChIJJ326ROcSkFQRBfUzOL2DSbo", title: "Marina Park")!) mapView.navigator?.setDestinations( destinations ) { routeStatus in guard routeStatus == .OK else { print("Handle route statuses that are not OK.") return } self.mapView.navigator?.isGuidanceActive = true self.mapView.locationSimulator?.simulateLocationsAlongExistingRoute() self.mapView.cameraMode = .following } } // Add a button to the view. func makeButton() { // A button to start navigation. let navButton = UIButton(frame: CGRect(x: 5, y: 150, width: 200, height: 35)) navButton.backgroundColor = .blue navButton.alpha = 0.5 navButton.setTitle("Start navigation", for: .normal) navButton.addTarget(self, action: #selector(startNav), for: .touchUpInside) self.mapView.addSubview(navButton) } }
Oculta o muestra el código Objective-C del controlador de vista de navegación.
/* * Copyright 2017 Google Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #import "ViewController.h" @import GoogleNavigation; @interface ViewController () @end @implementation ViewController { GMSMapView *_mapView; CLLocationManager *_locationManager; } - (void)loadView { _locationManager = [[CLLocationManager alloc] init]; // Set up the map view. GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:47.67 longitude:-122.20 zoom:14]; _mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera]; // Show the terms and conditions. NSString *companyName = @"Ride Sharing Co."; [GMSNavigationServices showTermsAndConditionsDialogIfNeededWithCompanyName:companyName callback:^(BOOL termsAccepted) { if (termsAccepted) { // Enable navigation if the user accepts the terms. _mapView.navigationEnabled = YES; _mapView.settings.compassButton = YES; // Request authorization to use the current device location. [_locationManager requestAlwaysAuthorization]; // Request authorization for alert notifications which deliver guidance instructions // in the background. UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; UNAuthorizationOptions options = UNAuthorizationOptionAlert; [center requestAuthorizationWithOptions:options completionHandler:^(BOOL granted, NSError *_Nullable error) { if (!error && granted) { NSLog(@"iOS Notification Permission: newly Granted"); } else { NSLog(@"iOS Notification Permission: Failed or Denied"); } }]; } else { // Handle rejection of the terms and conditions. } }]; self.view = _mapView; [self makeButton]; } // Create a route and initiate navigation. - (void)startNav { NSArray<GMSNavigationWaypoint *> *destinations = @[[[GMSNavigationWaypoint alloc] initWithPlaceID:@"ChIJnUYTpNASkFQR_gSty5kyoUk" title:@"PCC Natural Market"], [[GMSNavigationWaypoint alloc] initWithPlaceID:@"ChIJJ326ROcSkFQRBfUzOL2DSbo" title:@"Marina Park"]]; [_mapView.navigator setDestinations:destinations callback:^(GMSRouteStatus routeStatus){ [_mapView.locationSimulator simulateLocationsAlongExistingRoute]; _mapView.navigator.guidanceActive = YES; _mapView.navigator.sendsBackgroundNotifications = YES; _mapView.cameraMode = GMSNavigationCameraModeFollowing; }]; } // Add a button to the view. - (void)makeButton { // A button to start navigation. UIButton *navButton = [UIButton buttonWithType:UIButtonTypeCustom]; [navButton addTarget:self action:@selector(startNav) forControlEvents:UIControlEventTouchUpInside]; [navButton setTitle:@"Navigate" forState:UIControlStateNormal]; [navButton setBackgroundColor:[UIColor blueColor]]; navButton.frame = CGRectMake(5.0, 150.0, 100.0, 35.0); [_mapView addSubview:navButton]; } @end
Solicita al usuario las autorizaciones necesarias
Antes de usar el SDK de Navigation, el usuario debe aceptar los Términos y Condiciones, y autorizar el uso de los servicios de ubicación, que es obligatorio para la navegación. Si tu app se ejecutará en segundo plano, también debe solicitarle al usuario que autorice las notificaciones de alerta de instrucciones. En esta sección, se muestra cómo mostrar los mensajes de autorización obligatorios.
Cómo autorizar los servicios de ubicación
El SDK de Navigation usa servicios de ubicación, lo que requiere la autorización del usuario. Para habilitar los servicios de ubicación y mostrar el diálogo de autorización, sigue estos pasos:
- Agrega la clave
NSLocationAlwaysUsageDescription
aInfo.plist
. Para el valor, agrega una breve explicación de por qué tu app requiere servicios de ubicación. Por ejemplo: "Esta app necesita permiso para usar los servicios de ubicación para la navegación paso a paso".
Para mostrar el diálogo de autorización, llama a
requestAlwaysAuthorization()
de la instancia del administrador de ubicaciones.
self.locationManager.requestAlwaysAuthorization()
[_locationManager requestAlwaysAuthorization];
Cómo autorizar notificaciones de alerta para la guía en segundo plano
El SDK de Navigation necesita el permiso del usuario para proporcionar notificaciones de alerta cuando la app se ejecuta en segundo plano. Agrega el siguiente código para solicitarle permiso al usuario para mostrar estas notificaciones:
UNUserNotificationCenter.current().requestAuthorization(options: [.alert]) {
granted, error in
// Handle denied authorization to display notifications.
if !granted || error != nil {
print("User rejected request to display notifications.")
}
}
// Request authorization for alert notifications.
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
UNAuthorizationOptions options = UNAuthorizationOptionAlert;
[center requestAuthorizationWithOptions:options
completionHandler:
^(
BOOL granted,
NSError *_Nullable error) {
if (!error && granted) {
NSLog(@"iOS Notification Permission: newly Granted");
} else {
NSLog(@"iOS Notification Permission: Failed or Denied");
}
}];
Acepta los Términos y Condiciones.
Usa el siguiente código para mostrar el diálogo de los Términos y Condiciones y habilitar la navegación cuando el usuario acepte las condiciones. Ten en cuenta que este ejemplo incluye el código de los servicios de ubicación y las notificaciones de alerta de instrucciones (que se mostraron anteriormente).
let termsAndConditionsOptions = GMSNavigationTermsAndConditionsOptions(companyName: "Ride Sharing Co.")
GMSNavigationServices.showTermsAndConditionsDialogIfNeeded(
with: termsAndConditionsOptions) { termsAccepted in
if termsAccepted {
// Enable navigation if the user accepts the terms.
self.mapView.isNavigationEnabled = true
self.mapView.settings.compassButton = true
// Request authorization to use location services.
self.locationManager.requestAlwaysAuthorization()
// Request authorization for alert notifications which deliver guidance instructions
// in the background.
UNUserNotificationCenter.current().requestAuthorization(options: [.alert]) {
granted, error in
// Handle rejection of notification authorization.
if !granted || error != nil {
print("Authorization to deliver notifications was rejected.")
}
}
} else {
// Handle rejection of terms and conditions.
}
}
GMSNavigationTermsAndConditionsOptions *termsAndConditionsOptions = [[GMSNavigationTermsAndConditionsOptions alloc] initWithCompanyName:@"Ride Sharing Co."];
[GMSNavigationServices
showTermsAndConditionsDialogIfNeededWithOptions:termsAndConditionsOptions
callback:^(BOOL termsAccepted) {
if (termsAccepted) {
// Enable navigation if the user accepts the terms.
_mapView.navigationEnabled = YES;
_mapView.settings.compassButton = YES;
// Request authorization to use the current device location.
[_locationManager requestAlwaysAuthorization];
// Request authorization for alert notifications which deliver guidance instructions
// in the background.
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
UNAuthorizationOptions options = UNAuthorizationOptionAlert;
[center requestAuthorizationWithOptions:options
completionHandler:
^(
BOOL granted,
NSError *_Nullable error) {
if (!error && granted) {
NSLog(@"iOS Notification Permission: newly Granted");
} else {
NSLog(@"iOS Notification Permission: Failed or Denied");
}
}];
} else {
// Handle rejection of the terms and conditions.
}
}];
Crea una ruta y comienza la guía
Para trazar una ruta, llama al método setDestinations()
del navegador con un array que contenga uno o más destinos (GMSNavigationWaypoint
) para visitar. Si se calcula correctamente, la ruta se muestra en el mapa. Para iniciar la guía a lo largo de la ruta, comenzando con el primer destino, establece isGuidanceActive
en true
en la devolución de llamada.
En el ejemplo siguiente:
- Cómo crear una ruta nueva con dos destinos
- Guía de inicio.
- Habilita las notificaciones de guía en segundo plano.
- Simula el viaje a lo largo de la ruta (opcional).
- Configurar el modo de la cámara en "seguir" (opcional)
func startNav() {
var destinations = [GMSNavigationWaypoint]()
destinations.append(GMSNavigationWaypoint.init(placeID: "ChIJnUYTpNASkFQR_gSty5kyoUk",
title: "PCC Natural Market")!)
destinations.append(GMSNavigationWaypoint.init(placeID:"ChIJJ326ROcSkFQRBfUzOL2DSbo",
title:"Marina Park")!)
mapView.navigator?.setDestinations(destinations) { routeStatus in
self.mapView.navigator?.isGuidanceActive = true
self.mapView.locationSimulator?.simulateLocationsAlongExistingRoute()
self.mapView.cameraMode = .following
}
}
- (void)startNav {
NSArray<GMSNavigationWaypoint *> *destinations =
@[[[GMSNavigationWaypoint alloc] initWithPlaceID:@"ChIJnUYTpNASkFQR_gSty5kyoUk"
title:@"PCC Natural Market"],
[[GMSNavigationWaypoint alloc] initWithPlaceID:@"ChIJJ326ROcSkFQRBfUzOL2DSbo"
title:@"Marina Park"]];
[_mapView.navigator setDestinations:destinations
callback:^(GMSRouteStatus routeStatus){
[_mapView.locationSimulator simulateLocationsAlongExistingRoute];
_mapView.navigator.guidanceActive = YES;
_mapView.cameraMode = GMSNavigationCameraModeFollowing;
}];
}
Para obtener información sobre los IDs de lugar, consulta IDs de lugar.
Cómo configurar el modo de viaje
El modo de viaje determina qué tipo de ruta se recuperará y la forma en que se determina el curso del usuario. Puedes establecer uno de los cuatro modos de viaje para una ruta: en automóvil, en bicicleta, a pie y en taxi. En el modo de conducción y taxi, el rumbo del usuario se basa en la dirección de viaje. En el modo de bicicleta y a pie, el rumbo se representa por la dirección hacia la que está orientado el dispositivo.
Establece la propiedad travelMode
de la vista del mapa, como se muestra en el siguiente ejemplo:
self.mapView.travelMode = .cycling
_mapView.travelMode = GMSNavigationTravelModeCycling;
Cómo establecer rutas que se deben evitar
Usa las propiedades BOOL
avoidsHighways
y avoidsTolls
para evitar autopistas o rutas con peaje a lo largo de una ruta.
self.mapView.navigator?.avoidsTolls = true
_mapView.navigator.avoidsTolls = YES;
Buscador de PlaceID
Puedes usar el Buscador de PlaceID para encontrar los IDs de lugar que se usarán para los destinos de ruta. Agrega un destino desde un placeID
con GMSNavigationWaypoint
.
Texto flotante
Puedes agregar texto flotante en cualquier parte de la app, siempre y cuando no se oculte la atribución de Google. El SDK de Navigation no admite fijar el texto a una latitud/longitud en el mapa ni a una etiqueta. Para obtener más información, consulta Ventanas de información.