Создайте простое навигационное приложение для iOS в Swift с помощью SDK навигации платформы Google Maps. Создайте простое навигационное приложение для iOS в Swift с помощью SDK навигации платформы Google Maps.

1. Прежде чем начать

В этом практическом занятии вы научитесь создавать простое iOS-приложение, использующее SDK Google Maps Platform Navigation для навигации к заранее заданному пункту назначения.

Вот как будет выглядеть ваше приложение после завершения работы.

7e7c194a98d6dfa4.png

Предварительные требования

Что вы узнаете

  • Как создать простое iOS-приложение на Swift, использующее Navigation SDK для навигации к месту назначения.
  • Как интегрировать SDK навигации из удалённого репозитория Cocoapods.
  • Как управлять разрешениями на доступ к местоположению и пользовательским соглашением в соответствии с условиями использования Navigation SDK для конечных пользователей.
  • Как инициализировать SDK.
  • Как задать пункт назначения и запустить навигационное сопровождение.

Что вам понадобится

  • Последняя стабильная версия Xcode.
  • Учетная запись Google и проект с включенной функцией оплаты.
  • Устройство iOS или эмулируемое устройство, работающее в симуляторе XCode. Какой бы вариант вы ни выбрали, оно должно соответствовать минимальным требованиям для Navigation SDK .

2. Настройка

Если у вас еще нет учетной записи Google Cloud Platform и проекта с включенной оплатой, настройте свой проект Google Cloud, следуя инструкциям в разделе «Начало работы с Google Maps Platform» .

Выберите проект Google Cloud в консоли.

В консоли Cloud Console щелкните раскрывающееся меню «Проект» и выберите проект, который вы хотите использовать для этого практического занятия.

Выпадающее меню выбора проекта в консоли Google Cloud.

Включите SDK навигации в вашем проекте.

Для выполнения этого практического задания необходимо включить API и SDK платформы Google Maps в Google Cloud Marketplace .

Перейдите в раздел API и сервисы > Библиотека в консоли Google Cloud и найдите "Navigation SDK".

Вы должны увидеть один результат поиска.

Экран библиотеки API в консоли Google Cloud, отображающий страницу Navigation SDK.

Нажмите «Navigation SDK» , чтобы открыть страницу с подробными сведениями о продукте. Нажмите «Enable» , чтобы включить SDK в вашем проекте.

Повторите этот процесс для Google Maps SDK для iOS .

Создайте ключ API

Сгенерируйте ключ API на странице «Учетные данные» в Cloud Console. Для всех запросов к Google Maps Platform требуется ключ API. На странице «Учетные данные» в консоли нажмите «+Создать учетные данные» в верхней части страницы и выберите «Ключ API» из предложенных вариантов.

Для использования в производственной среде рекомендуется установить ограничение на использование вашего API-ключа, но в рамках данного практического занятия это необязательно.

3. Получите файлы примера проекта.

В этом разделе описывается, как создать базовый пустой проект XCode, клонировав файлы из репозитория GitHub для этого практического занятия. Репозиторий GitHub содержит версии кода для практического занятия до и после его завершения. Практическое занятие начнется с пустого шаблона проекта и будет постепенно доходить до конечного состояния. Вы можете использовать готовый проект из репозитория в качестве образца, если у вас возникнут трудности.

Клонируйте репозиторий или скачайте код.

Перейдите в директорию, где вы хотите сохранить код для лабораторной работы.

Затем клонируйте репозиторий или скачайте код:

git clone https://github.com/googlemaps-samples/codelab-navigation-101-ios-swift

Если у вас не установлен Git, нажмите эту кнопку, чтобы получить код:

Чтобы вы могли как можно быстрее начать работу, в папке Starter репозитория содержится стартовый код, который поможет вам следовать инструкциям этого практического занятия. Также есть готовый проект Solution , если вы захотите перейти к следующему этапу или проверить свой прогресс в любое время. Чтобы использовать проект решения, вам необходимо выполнить инструкции по установке с помощью Cocoapods, приведенные ниже, а затем запустить команду "pod update" из папки solution/Navigation SDK Codelab .

После клонирования репозитория локально, используйте Xcode, чтобы открыть папку Starter как существующий проект. Убедитесь, что проект компилируется и запускается.

Подключите устройство или настройте симулятор Xcode.

4. Добавьте SDK навигации в ваше приложение.

Существует три способа интеграции Navigation SDK в проект Xcode: в этом практическом занятии используется CocoaPods . Подробную информацию об интеграции с помощью Swift Package Manager или о ручной установке путем загрузки SDK см. в разделе «Создание проекта Xcode и установка Navigation SDK» в документации Navigation SDK.

Установка с помощью Cocoapods

Если у вас еще нет инструмента CocoaPods, установите его на macOS, выполнив следующую команду в терминале. Подробности см. в руководстве по началу работы с CocoaPods .

sudo gem install cocoapods

Создайте новый файл с именем Podfile в папке вашего проекта, внутри папки starter/Navigation SDK Codelab (в Xcode: File > New > File > Other > Empty, сохраните как "Podfile")

Добавьте следующее содержимое в ваш Podfile :

source 'https://github.com/CocoaPods/Specs.git'

platform :ios, '15.0'

target 'Navigation SDK Codelab' do
  pod 'GoogleNavigation', '9.1.1'
end

Сохраните Podfile .

Откройте терминал и перейдите в каталог, где вы сохранили свой Podfile (это должна быть папка "starter/Navigation SDK Codelab" в репозитории codelab).

cd "<path-to-starter-project-folder>/Navigation SDK Codelab"

Выполните команду pod install . Это установит API, указанные в Podfile , а также все необходимые зависимости.

pod install

Закройте Xcode, а затем откройте файл .xcworkspace вашего проекта, чтобы запустить Xcode. С этого момента для открытия проекта необходимо использовать файл .xcworkspace.

Убедитесь, что в структуру проекта добавлена ​​директория Pods и что она содержит Pod-ы "GoogleMaps" и "GoogleNavigation".

6e81772ee067d452.png

Добавьте свой API-ключ

Добавьте свой API-ключ в файл AppDelegate.swift следующим образом:

  1. Добавьте следующие операторы импорта:
import GoogleMaps
import GoogleNavigation
  1. Добавьте следующее в метод application(_:didFinishLaunchingWithOptions:) :
GMSServices.provideAPIKey("YOUR_API_KEY")

Замените "YOUR_API_KEY" на ключ API, который вы создали на предыдущем шаге.

Создайте свой проект и исправьте все ошибки.

5. Настройка разрешений приложения

Навигационный SDK использует сигналы GPS для определения местоположения на дороге и предоставления пошаговых инструкций, поэтому вашему приложению потребуется запросить у пользователя разрешение на доступ к точным данным о местоположении.

Для этого вам потребуется добавить несколько свойств в файл Info.plist вашего приложения в Xcode, добавить в приложение код для запроса разрешения у пользователя во время выполнения и обрабатывать любые ошибки, такие как отказ в предоставлении разрешения или недоступность местоположения.

Откройте файл Info.plist в Xcode. Он должен выглядеть примерно так.

6532a85bd9ac8fb4.png

Запросить разрешение на определение точного местоположения.

Добавить новые значения можно, наведя указатель мыши на строку «Список свойств информации», пока не появится значок «+». Щелкните «+», чтобы открыть диалоговое окно с предлагаемыми именами свойств, но обратите внимание, что вы также можете добавлять свойства вручную.

Добавьте следующие свойства и значения в файл Info.plist:

Свойство

Ценить

Конфиденциальность - Местоположение: Всегда и при использовании. Описание использования.

Для предоставления пошаговой навигации этому приложению требуется информация о местоположении вашего устройства.

Конфиденциальность - Местоположение при использовании Описание использования

Для предоставления пошаговой навигации этому приложению требуется информация о местоположении вашего устройства.

позволяет обновлять местоположение в фоновом режиме

ДА

Запросить разрешение на определение местоположения в фоновом режиме.

Добавьте следующие свойства и значения в файл Info.plist:

UIBackgroundModes > Добавить строку > Item 0: App registers for location updates (выберите это значение из выпадающего списка предложений)

После завершения работы файл Info.plist должен выглядеть примерно так.

3b0c49018451d0ff.png

Запросить доступ к местоположению во время выполнения

Добавьте следующие операторы импорта в файл ViewController.swift :

import GoogleNavigation

Добавьте следующее объявление в класс ViewController:

var locationManager: CLLocationManager!

Добавьте переопределение метода для loadView() и вызовите locationManager.requestAlwaysAuthorization() :

override func loadView() {
        locationManager = CLLocationManager()
        locationManager.requestAlwaysAuthorization()

Теперь ваше приложение будет запрашивать у пользователя его местоположение и предоставлять его приложению, если он предоставит разрешение.

Запросить разрешение на отображение уведомлений

Добавьте следующий код в метод loadView(), чтобы запросить у пользователя разрешение на отображение уведомлений, которое потребуется для отображения инструкций по выполнению навигационных действий.

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.")
          }
        }

Соберите и запустите приложение и убедитесь, что вам предлагается поделиться местоположением и включить уведомления.

ad5f665a21170c49.png

6. Добавить навигационный пользовательский интерфейс.

На этом шаге вы добавите карту и настроите её для отображения местоположения. Затем вы покажете пользователю диалоговое окно с условиями использования Navigation SDK.

Добавьте карту в свое приложение.

Добавьте эту строку, чтобы объявить переменную GMSMapView в вашем ViewController.

var mapView: GMSMapView!

Добавьте следующий код в loadView() в файле Viewcontroller.swift , чтобы инициализировать карту.

let camera = GMSCameraPosition.camera(withLatitude: 51.483174, longitude: -0.177369, zoom: 14)
let options = GMSMapViewOptions()
options.camera = camera
options.frame = .zero
        
mapView = GMSMapView(options: options)
view = mapView

Создайте и запустите приложение, и вы должны увидеть карту с центром в юго-западной части Лондона.

1d46ce5c0851cae3.png

Показать диалоговое окно с условиями использования продукта Navigation SDK

Добавьте следующий код в файл ViewController.swift в тот же метод loadView() , что и предыдущий код. Это отобразит условия использования Navigation SDK для конечных пользователей. Если они не будут приняты, навигация не будет включена.

// Show the terms and conditions.
let companyName = "Navigation SDK Codelab"
GMSNavigationServices.showTermsAndConditionsDialogIfNeeded(withCompanyName: companyName) { termsAccepted in
  if termsAccepted {
    // Enable navigation if the user accepts the terms.
    self.mapView.isNavigationEnabled = true
    // Request authorization for alert notifications which deliver guidance instructions
    // in the background.
  } else {
    // Handle the case when the user rejects the terms and conditions.
  }
}

Соберите и запустите приложение, чтобы увидеть диалоговое окно.

29f17ae5b4c07c9f.png

7. Добавьте обработчики событий для ключевых событий навигации.

На этом шаге вы узнаете, как настроить обработчики ключевых событий, таких как прибытие в пункт назначения или изменение маршрута водителем.

Для отслеживания этих событий ваш контроллер представления должен поддерживать протокол GMSNavigatorListener .

Добавьте этот протокол в определение класса в файле ViewController.swift .

class ViewController: UIViewController,
                      GMSNavigatorListener {

Теперь добавьте строку кода для настройки обработчика событий в loadView():

// Add a listener for GMSNavigator.
mapView.navigator?.add(self)

Наконец, добавьте в свой класс два метода для обработки возникающих событий.

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

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

8. Укажите пункт назначения и начните навигацию.

В этом разделе вы узнаете, как задать пункт назначения и запустить навигацию.

Создайте новую функцию для логики навигации.

Во-первых, добавьте в ваш ViewController новую функцию с именем startNav() . Она будет содержать логику для установки пункта назначения и начала навигации.

// Create a route and start guidance.
@objc func startNav() {
}

Создайте Waypoint для пункта назначения.

Далее создайте массив пунктов назначения, каждый из которых будет содержать одну путевую точку.

// Create a route and start guidance.
@objc func startNav() {
  var destinations = [GMSNavigationWaypoint]()
  destinations.append(
    GMSNavigationWaypoint.init(
      placeID: "ChIJH-tBOc4EdkgRJ8aJ8P1CUxo",
      title: "Trafalgar Square")!)
}

Вызовите метод setDestinations() и обработайте ответ.

Далее вызовите метод setDestinations и обработайте возвращаемое значение GMSRouteStatus .

Если GMSRouteStatus имеет значение "OK", запустите навигацию, установив isGuidanceActive=true для объекта navigator mapView . В противном случае выведите сообщение об ошибке.

Если возвращаемое значение GMSRouteStatus равно "OK", начните имитацию движения по маршруту, вызвав метод mapView.locationSimulator.simulateLocationsAlongExistingRoute() .

// Create a route and start guidance.
@objc func startNav() {
  var destinations = [GMSNavigationWaypoint]()
    destinations.append(
      GMSNavigationWaypoint.init(
        placeID: "ChIJH-tBOc4EdkgRJ8aJ8P1CUxo",
          title: "Trafalgar Square")!)
      
  mapView.navigator?.setDestinations(
    destinations
  ) { routeStatus in
    guard routeStatus == .OK else {
      print("Handle route statuses that are not OK.")
      return
    }
    //If routeStatus is OK, start guidance.
    self.mapView.navigator?.isGuidanceActive = true
    //start simulating driving along the route. self.mapView.locationSimulator?.simulateLocationsAlongExistingRoute()
    self.mapView.cameraMode = .following
  }
}

Обработка распространенных статусов ошибок

Полезно более явно обрабатывать ошибки GMSRouteStatus , особенно при отладке начальных проблем вашего нового приложения. Например, вы можете обнаружить, что на начальном этапе чаще получаете ошибки, связанные с разрешением местоположения, ключом API или «маршрут не найден», из-за настроек отладки, поэтому может быть полезно обрабатывать эти состояния ошибок.

Добавьте код, который обрабатывает эти конкретные случаи и выводит сообщение в консоль.

mapView.navigator?.setDestinations(
  destinations
) { routeStatus in
    guard routeStatus == .OK else {
      print("Handle route statuses that are not OK.")
      switch routeStatus {
       case .locationUnavailable:
        print("Location unavailable.") //check permissions
      case .noRouteFound:
        print("No route found.") //check start location and destination
      case .waypointError:
        print("Waypoint error") //check Place ID
      default:
        print("Not sure what happened")
      }
    return
  }

Добавьте кнопку для запуска навигации.

Наконец, добавьте кнопку в пользовательский интерфейс и свяжите её с методом startNav. Создайте метод makeButton() со следующим кодом. Вызовите функцию makeButton() из loadView() .

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

Создайте и запустите своё приложение.

Примечание: запуск кода в

startNav()

позвонит

setDestinations()

Метод, при котором плата взимается после использования первых 1000 пунктов назначения. Дополнительную информацию см. в разделе «Использование и выставление счетов» .

9. Поздравляем!

Отлично! Вы прибыли в пункт назначения!

7a69dcb75c904d7.png

Вы создали простое приложение, которое предоставляет пошаговые навигационные указания к месту назначения, используя SDK для навигации платформы Google Maps.

Вы настроили разрешения приложения и диалоговое окно условий использования Navigation SDK, а также указали пункт назначения, используя идентификатор места (Place ID). Вы обработали различные состояния успеха и ошибки в своем приложении.

10. Дальнейшее развитие событий

Если вы хотите вывести разработку своего приложения на новый уровень, ознакомьтесь со следующими темами для вдохновения.

  • Отслеживайте дополнительные события навигации . Добавьте код для отображения сообщения, если оставшееся время или расстояние превышают пороговое значение.
  • Настройте интерфейс навигации .
  • Если хотите более сложную задачу, попробуйте добавить средство выбора места из Places API, чтобы пользователь мог указать пункт назначения. Подсказка: в демонстрационных приложениях Navigation SDK есть пример реализации. Запустите команду pod try GoogleNavigation в папке вашего проекта, чтобы посмотреть код.