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

Предварительные требования
- Знание основ разработки iOS-приложений на Swift.
- Необходимо иметь представление об основных концепциях Google Maps SDK, таких как создание карты с центром в определенном месте .
Что вы узнаете
- Как создать простое 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 щелкните раскрывающееся меню «Проект» и выберите проект, который вы хотите использовать для этого практического занятия.

Включите SDK навигации в вашем проекте.
Для выполнения этого практического задания необходимо включить API и SDK платформы Google Maps в Google Cloud Marketplace .
Перейдите в раздел 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".

Добавьте свой API-ключ
Добавьте свой API-ключ в файл AppDelegate.swift следующим образом:
- Добавьте следующие операторы импорта:
import GoogleMaps
import GoogleNavigation
- Добавьте следующее в метод
application(_:didFinishLaunchingWithOptions:):
GMSServices.provideAPIKey("YOUR_API_KEY")
Замените "YOUR_API_KEY" на ключ API, который вы создали на предыдущем шаге.
Создайте свой проект и исправьте все ошибки.
5. Настройка разрешений приложения
Навигационный SDK использует сигналы GPS для определения местоположения на дороге и предоставления пошаговых инструкций, поэтому вашему приложению потребуется запросить у пользователя разрешение на доступ к точным данным о местоположении.
Для этого вам потребуется добавить несколько свойств в файл Info.plist вашего приложения в Xcode, добавить в приложение код для запроса разрешения у пользователя во время выполнения и обрабатывать любые ошибки, такие как отказ в предоставлении разрешения или недоступность местоположения.
Откройте файл Info.plist в Xcode. Он должен выглядеть примерно так.

Запросить разрешение на определение точного местоположения.
Добавить новые значения можно, наведя указатель мыши на строку «Список свойств информации», пока не появится значок «+». Щелкните «+», чтобы открыть диалоговое окно с предлагаемыми именами свойств, но обратите внимание, что вы также можете добавлять свойства вручную.
Добавьте следующие свойства и значения в файл Info.plist:
Свойство | Ценить |
Конфиденциальность - Местоположение: Всегда и при использовании. Описание использования. | Для предоставления пошаговой навигации этому приложению требуется информация о местоположении вашего устройства. |
Конфиденциальность - Местоположение при использовании Описание использования | Для предоставления пошаговой навигации этому приложению требуется информация о местоположении вашего устройства. |
позволяет обновлять местоположение в фоновом режиме | ДА |
Запросить разрешение на определение местоположения в фоновом режиме.
Добавьте следующие свойства и значения в файл Info.plist:
UIBackgroundModes > Добавить строку > Item 0: App registers for location updates (выберите это значение из выпадающего списка предложений)
После завершения работы файл Info.plist должен выглядеть примерно так.

Запросить доступ к местоположению во время выполнения
Добавьте следующие операторы импорта в файл 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.")
}
}
Соберите и запустите приложение и убедитесь, что вам предлагается поделиться местоположением и включить уведомления.

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

Показать диалоговое окно с условиями использования продукта 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.
}
}
Соберите и запустите приложение, чтобы увидеть диалоговое окно.

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. Поздравляем!
Отлично! Вы прибыли в пункт назначения!

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