Navigasyon etkinliklerini dinleme

Uygulamanızın, kullanıcı bir rota üzerinde gezinirken değişen çeşitli etkinlikleri dinleyip yanıtlamasını sağlamak için bu rehberi kullanın. Bu kılavuzda, rota tanımlama değil, yalnızca rota üzerindeki etkinliklere yanıt verme ele alınmaktadır.

Genel Bakış

iOS için Navigasyon SDK'sı, kullanıcının konumu ve rotadaki koşullarla ilişkili dinleyiciler, önemli zaman ve mesafe verileri sağlar. Uygulamanızın, haritanın görüntüleme denetleyicisinde şu dinleyicilerin protokollerini benimsemesi gerekir: GMSRoadSnappedLocationProviderListener ve GMSNavigatorListener.

Bu listede, gezinme etkinlikleri için kullanılabilen dinleyici yöntemleri gösterilmektedir:

Kodu görme

/*
 * Copyright 2020 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,
  GMSNavigatorListener,
  GMSRoadSnappedLocationProviderListener
{

  var mapView: GMSMapView!
  var locationManager: CLLocationManager!

  override func loadView() {

    locationManager = CLLocationManager()

    let camera = GMSCameraPosition.camera(withLatitude: 47.67, longitude: -122.20, zoom: 14)
    mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)

    // Add listeners for GMSNavigator and GMSRoadSnappedLocationProvider.
    mapView.navigator?.add(self)
    mapView.roadSnappedLocationProvider?.add(self)

    // Set the time update threshold (seconds) and distance update threshold (meters).
    mapView.navigator?.timeUpdateThreshold = 10
    mapView.navigator?.distanceUpdateThreshold = 100

    // 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

        // 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("Authorization to deliver notifications was rejected.")
          }
        }
      } else {
        // Handle the case when the user rejects the terms and conditions.
      }
    }

    view = mapView

    makeButton()
  }

  // Create a route and start guidance.
  @objc 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.cameraMode = .following
      self.mapView.locationSimulator?.simulateLocationsAlongExistingRoute()
    }

    mapView.roadSnappedLocationProvider?.startUpdatingLocation()
  }

  // Listener to handle continuous location updates.
  func locationProvider(
    _ locationProvider: GMSRoadSnappedLocationProvider,
    didUpdate location: CLLocation
  ) {
    print("Location: \(location.description)")
  }

  // Listener to handle speeding events.
  func navigator(
    _ navigator: GMSNavigator, didUpdateSpeedingPercentage percentageAboveLimit: CGFloat
  ) {
    print("Speed is \(percentageAboveLimit) above the limit.")
  }

  // Listener to handle arrival events.
  func navigator(_ navigator: GMSNavigator, didArriveAt waypoint: GMSNavigationWaypoint) {
    print("You have arrived at: \(waypoint.title)")
    mapView.navigator?.continueToNextDestination()
    mapView.navigator?.isGuidanceActive = true
  }

  // Listener for route change events.
  func navigatorDidChangeRoute(_ navigator: GMSNavigator) {
    print("The route has changed.")
  }

  // Listener for time to next destination.
  func navigator(_ navigator: GMSNavigator, didUpdateRemainingTime time: TimeInterval) {
    print("Time to next destination: \(time)")
  }

  // Delegate for distance to next destination.
  func navigator(
    _ navigator: GMSNavigator,
    didUpdateRemainingDistance distance: CLLocationDistance
  ) {
    let miles = distance * 0.00062137
    print("Distance to next destination: \(miles) miles.")
  }

  // Delegate for traffic updates to next destination
  func navigator(
    _ navigator: GMSNavigator,
    didUpdate delayCategory: GMSNavigationDelayCategory
  ) {
    print("Delay category to next destination: \(String(describing: delayCategory)).")
  }

  // Delegate for suggested lighting mode changes.
  func navigator(
    _ navigator: GMSNavigator,
    didChangeSuggestedLightingMode lightingMode: GMSNavigationLightingMode
  ) {
    print("Suggested lighting mode has changed: \(String(describing: lightingMode))")

    // Change to the suggested lighting mode.
    mapView.lightingMode = lightingMode
  }

  // Add a button to the view.
  func makeButton() {
    // 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)
  }

}
/*
 * Copyright 2020 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 () <GMSNavigatorListener, GMSRoadSnappedLocationProviderListener>

@end

@implementation ViewController {
  GMSMapView *_mapView;
  CLLocationManager *_locationManager;
}

- (void)loadView {

  _locationManager = [[CLLocationManager alloc] init];

  GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:47.67
                                                          longitude:-122.20
                                                               zoom:14];
  _mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];

  // Add listeners for GMSNavigator and GMSRoadSnappedLocationProvider.
  [_mapView.navigator addListener:self];
  [_mapView.roadSnappedLocationProvider addListener:self];

  // Set the time update threshold (seconds) and distance update threshold (meters).
  _mapView.navigator.timeUpdateThreshold = 10;
  _mapView.navigator.distanceUpdateThreshold = 100;

  // 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;

       // Request authorization to use location services.
       [_locationManager requestAlwaysAuthorization];

     } else {
       // Handle the case when the user rejects 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.navigator.guidanceActive = YES;
                               _mapView.navigator.sendsBackgroundNotifications = YES;
                               _mapView.cameraMode = GMSNavigationCameraModeFollowing;
                               [_mapView.locationSimulator simulateLocationsAlongExistingRoute];
                             }];

  [_mapView.roadSnappedLocationProvider startUpdatingLocation];
}

#pragma mark - GMSNavigatorListener
// Listener for continuous location updates.
- (void)locationProvider:(GMSRoadSnappedLocationProvider *)locationProvider
      didUpdateLocation:(CLLocation *)location {
  NSLog(@"Location: %@", location.description);
}

// Listener to handle speeding events.
- (void)navigator:(GMSNavigator *)navigator
    didUpdateSpeedingPercentage:(CGFloat)percentageAboveLimit {
  NSLog(@"Speed is %f percent above the limit.", percentageAboveLimit);
}

// Listener to handle arrival events.
- (void)navigator:(GMSNavigator *)navigator didArriveAtWaypoint:(GMSNavigationWaypoint *)waypoint {
  NSLog(@"You have arrived at: %@", waypoint.title);
  [_mapView.navigator continueToNextDestination];
  _mapView.navigator.guidanceActive = YES;
}

// Listener for route change events.
- (void)navigatorDidChangeRoute:(GMSNavigator *)navigator {
  NSLog(@"The route has changed.");
}

// Listener for time to next destination.
- (void)navigator:(GMSNavigator *)navigator didUpdateRemainingTime:(NSTimeInterval)time {
  NSLog(@"Time to next destination: %f", time);
}

// Listener for distance to next destination.
- (void)navigator:(GMSNavigator *)navigator
      didUpdateRemainingDistance:(CLLocationDistance)distance {
  double miles = distance * 0.00062137;
  NSLog(@"%@", [NSString stringWithFormat:@"Distance to next destination: %.2f.", miles]);
}

// Listener for traffic updates for next destination
- (void)navigator:(GMSNavigator *)navigator
    didUpdateDelayCategory:(GMSNavigationDelayCategory)delayCategory {
  NSLog(@"Delay category to next destination: %ld.", delayCategory);
}

// Listener for suggested lighting mode changes.
-(void)navigator:(GMSNavigator *)navigator
      didChangeSuggestedLightingMode:(GMSNavigationLightingMode)lightingMode {
  NSLog(@"Suggested lighting mode has changed: %ld", (long)lightingMode);

  // Change to the suggested lighting mode.
  _mapView.lightingMode = lightingMode;
}

#pragma mark - Programmatic UI elements

// Add a button to the view.
- (void)makeButton {
  // 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 setAlpha:0.5];
  navButton.frame = CGRectMake(5.0, 150.0, 100.0, 35.0);
  [_mapView addSubview:navButton];
}

@end

Gerekli protokollere uygunluğu beyan etme

Görüntüleme denetleyicisi, gezinme yöntemlerini uygulamadan önce aşağıdaki protokolleri benimsemelidir:

SwiftObjective-C

class ViewController: UIViewController, GMSNavigatorListener,
GMSRoadSnappedLocationProviderListener {

@interface ViewController () <GMSNavigatorListener,
GMSRoadSnappedLocationProviderListener>

@end

Gezinme protokollerini benimsedikten sonra dinleyicileri görüntü kontrol cihazına ayarlayın. Örneğin, viewDidLoad() yöntemine aşağıdaki kodu ekleyebilirsiniz.

SwiftObjective-C

mapView.navigator?.add(self) mapView.roadSnappedLocationProvider?.add(self)

[_mapView.navigator addListener:self]; [_mapView.roadSnappedLocationProvider
addListener:self];

Konum güncellemelerini alma veya durdurma

Kullanıcının haritada ilerleme durumunu göstermek için konum güncellemeleri gerekir.

location örneği aşağıdaki özellikleri gösterir:

Konum mülkü Açıklama
rakım Mevcut rakım.
coordinate.latitude Yola göre yakalanan mevcut enlem koordinatı.
coordinate.longitude Yola göre yakalanan mevcut boylam koordinatı.
kurs Derece cinsinden mevcut yön.
hız Mevcut hız.
timestamp Mevcut okumanın tarihi/saati.

Sürekli konum güncellemeleri almak için mapView.roadSnappedLocationProvider.startUpdatingLocation işlevini çağırın ve didUpdateLocation etkinliğini işlemek için GMSRoadSnappedLocationProviderListener işlevini kullanın.

Aşağıdaki örnekte startUpdatingLocation çağrısı gösterilmektedir:

SwiftObjective-C

mapView.roadSnappedLocationProvider.startUpdatingLocation()

[_mapView.roadSnappedLocationProvider startUpdatingLocation];

Aşağıdaki kod, didUpdateLocation etkinliğini işleyen bir GMSRoadSnappedLocationProviderListener oluşturur.

SwiftObjective-C

func locationProvider(_ locationProvider: GMSRoadSnappedLocationProvider,
didUpdate location: CLLocation) { print("Location: \(location.description)") }

-   (void)locationProvider:(GMSRoadSnappedLocationProvider *)locationProvider
    didUpdateLocation:(CLLocation *)location { NSLog(@"Location: %@",
    location.description); }

Uygulama arka plandayken konum güncellemeleri almak için allowsBackgroundLocationUpdates değerini true olarak ayarlayın:

SwiftObjective-C

mapView.roadSnappedLocationProvider.allowsBackgroundLocationUpdates = true

 _mapView.roadSnappedLocationProvider.allowsBackgroundLocationUpdates = YES;

Varış etkinliklerini algılama

Uygulamanız, bir hedefe ne zaman ulaşıldığını algılamak için didArriveAtWaypoint etkinliğini kullanır. continueToNextDestination()'yi çağırıp rehberliği yeniden etkinleştirerek rehberliği devam ettirebilir ve sonraki yol noktasına geçebilirsiniz. Uygulamanız, continueToNextDestination() çağrısından sonra rehberliği yeniden etkinleştirmelidir.

Uygulama continueToNextDestination'ü aradıktan sonra, gezginin önceki hedefle ilgili verileri artık yoktur. Bir rota adımı hakkındaki bilgileri analiz etmek istiyorsanız continueToNextDestination()'ü aramadan önce bu bilgileri navigasyon cihazından almanız gerekir.

Aşağıdaki kod örneğinde, didArriveAtWaypoint etkinliğini işleme yöntemi gösterilmektedir:

SwiftObjective-C

func navigator(_ navigator: GMSNavigator, didArriveAt waypoint:
GMSNavigationWaypoint) { print("You have arrived at: \(waypoint.title)")
mapView.navigator?.continueToNextDestination()
mapView.navigator?.isGuidanceActive = true }

-   (void)navigator:(GMSNavigator *)navigator
    didArriveAtWaypoint:(GMSNavigationWaypoint *)waypoint { NSLog(@"You have
    arrived at: %@", waypoint.title); [_mapView.navigator
    continueToNextDestination]; _mapView.navigator.guidanceActive = YES; }

Rota değişikliği güncellemeleri alma

Rota her değiştirildiğinde bildirim almak için navigatorDidChangeRoute etkinliğini işleyen bir yöntem oluşturun. GMSNavigator mülkünün routeLegs ve currentRouteLeg özelliklerini kullanarak yeni yola erişebilirsiniz.

SwiftObjective-C

func navigatorDidChangeRoute(_ navigator: GMSNavigator) { print("The route has
changed.") }

-   (void)navigatorDidChangeRoute:(GMSNavigator *)navigator { NSLog(@"The route
    has changed."); }

Hedefe varış süresi güncellemeleri alma

Hedefe varış süresiyle ilgili sürekli güncellemeler almak için didUpdateRemainingTime etkinliğini işleyen bir yöntem oluşturun. time parametresi, bir sonraki hedefe ulaşılana kadar geçen tahmini süreyi saniye cinsinden sağlar.

SwiftObjective-C

func navigator(_ navigator: GMSNavigator, didUpdateRemainingTime time:
TimeInterval) { print("Time to next destination: \(time)") }

-   (void)navigator:(GMSNavigator *)navigator
    didUpdateRemainingTime:(NSTimeInterval)time { NSLog(@"Time to next
    destination: %f", time); }

Bir sonraki hedefe tahmini süredeki minimum değişikliği ayarlamak için timeUpdateThreshold mülkünü GMSNavigator olarak ayarlayın. Değer saniye cinsinden belirtilir. Bu özellik ayarlanmazsa hizmetler bir saniyelik varsayılan değeri kullanır.

SwiftObjective-C

navigator?.timeUpdateThreshold = 10

navigator.timeUpdateThreshold = 10;

Hedefe olan mesafeyle ilgili güncellemeler alma

Hedefe olan mesafeyle ilgili sürekli güncellemeler almak için didUpdateRemainingDistance etkinliğini işleyen bir yöntem oluşturun. distance parametresi, bir sonraki hedefe olan tahmini mesafeyi (metre cinsinden) sağlar.

SwiftObjective-C

func navigator(_ navigator: GMSNavigator, didUpdateRemainingDistance distance:
CLLocationDistance) { let miles = distance * 0.00062137 print("Distance to next
destination: \(miles) miles.") }

-   (void)navigator:(GMSNavigator *)navigator
    didUpdateRemainingDistance:(CLLocationDistance)distance { double miles =
    distance * 0.00062137; NSLog(@"%@", [NSString stringWithFormat:@"Distance to
    next destination: %.2f.", miles]); }

Sonraki hedefe olan tahmini mesafedeki minimum değişikliği ayarlamak için distanceUpdateThreshold mülkünü GMSNavigator olarak ayarlayın (değer metre cinsinden belirtilir). Bu özellik ayarlanmazsa hizmetler bir metrelik varsayılan değeri kullanır.

SwiftObjective-C

navigator?.distanceUpdateThreshold = 100

navigator.distanceUpdateThreshold = 100;

Trafik güncellemeleri alma

Kalan rotanın trafik akışıyla ilgili sürekli güncellemeler almak için didUpdateDelayCategory etkinliğini işleyen bir yöntem oluşturun. delayCategoryToNextDestination çağrısı, 0 ila 3 arasında bir değer sağlayan GMSNavigationDelayCategory değerini döndürür. Kategorideki güncellemeler, uygulama kullanıcısının mevcut konumuna göre yapılır. Trafik verileri kullanılamıyorsa GMSNavigationDelayCategory 0 değerini döndürür. 1-3 arasındaki sayılar, hafiften ağıra doğru artan akışı gösterir.

SwiftObjective-C

func navigator(_ navigator: GMSNavigator, didUpdate delayCategory:
GMSNavigationDelayCategory) { print("Traffic flow to next destination:
\(delayCategory)") }

-   (void)navigator:(GMSNavigator *)navigator
    didUpdateDelayCategory:(GMSNavigationDelayCategory)delayCategory {
    NSLog(@"Traffic flow to next destination: %ld", (long)delayCategory); }

GMSNavigationDelayCategory mülkü aşağıdaki gecikme düzeylerini gösterir:

Gecikme kategorisi Açıklama
GMSNavigationDelayCategoryNoData 0: Kullanılamıyor, trafik için veri yok veya :
rota.
GMSNavigationDelayCategoryHeavy 1 - Ağır.
GMSNavigationDelayCategoryMedium 2 - Orta.
GMSNavigationDelayCategoryLight 3 - Işık.

Hız sınırı ihlali güncellemeleri alma

Bir sürücü hız sınırını aştığında güncelleme almak için didUpdateSpeedingPercentage etkinliğini işleyen bir yöntem oluşturun.

SwiftObjective-C

// Listener to handle speeding events. func navigator( _ navigator:
GMSNavigator, didUpdateSpeedingPercentage percentageAboveLimit: CGFloat ) {
print("Speed is \(percentageAboveLimit) above the limit.") }

// Listener to handle speeding events. - (void)navigator:(GMSNavigator
*)navigator didUpdateSpeedingPercentage:(CGFloat)percentageAboveLimit {
NSLog(@"Speed is %f percent above the limit.", percentageAboveLimit); }

Önerilen aydınlatma modunu değiştirme

Aydınlatmadaki tahmini değişikliklerle ilgili güncellemeler almak için didChangeSuggestedLightingMode etkinliğini işleyen bir yöntem oluşturun.

SwiftObjective-C

// Define a listener for suggested changes to lighting mode. func navigator(_
navigator: GMSNavigator, didChangeSuggestedLightingMode lightingMode:
GMSNavigationLightingMode) { print("Suggested lighting mode has changed:
\(String(describing: lightingMode))")

 // Make the suggested change. mapView.lightingMode = lightingMode }

// Define a listener for suggested changes to lighting mode.
-(void)navigator:(GMSNavigator *)navigator didChangeSuggestedLightingMode:
(GMSNavigationLightingMode)lightingMode { NSLog(@"Suggested lighting mode has
changed: %ld", (long)lightingMode);

 // Make the suggested change. _mapView.lightingMode = lightingMode; }