
Содержание статьи
автор Нео Игадаро

Карты реального времени очень популярны в наше время. Особенно сейчас, когда существует много транспортных служб по требованию, таких как Uber и Lyft, имеющие отчеты о местонахождении в реальном времени. В этой статье мы узнаем, как создать карту реального времени на iOS с помощью Pusher.
Прежде чем мы продолжим, вам нужно убедиться, что вы отвечаете всем нижеприведенным требованиям.
- MacBook (Xcode работает только на Mac).
- Xcode установлен на вашем автомобиле.
- Знание JavaScript (Node.js).
- Знание Swift и использование Xcode. Вы можете начать здесь.
- NPM и Node.js установлены локально.
- Менеджер пакетов Cocoapods установлен локально.
- Ключ API Google iOS. См. инструкции по получению ключа.
- Программа Pusher. Создайте его здесь.
Для выполнения этого руководства необходимо базовое понимание Swift и Node.js.
Предположим, что у вас есть все требования, начнём. Это экранная запись того, что мы будем строить:

Как вы можете видеть на демонстрации, каждый раз, когда местоположение обновляется, изменения отображаются на обоих устройствах. Это то, что мы хотим повторить. Давайте начнем.
Настройка нашего приложения для iOS
Запустите Xcode и создайте новый проект «Single-app». Вы можете называть проект как угодно.

При создании проекта закройте Xcode. Откройте свой терминал, cd
в корневой каталог программы и запустите команду ниже, чтобы инициализировать Cocoapods в проекте:
$ pod init
Команда выше создаст a Podfile
в корневом каталоге нашей программы. В этом Podfile
, мы укажем зависимости наших проектов и позволим Cocoapods извлекать их и управлять ими. Откройте Podfile
и замените содержимое файла на содержимое ниже:
platform :ios, '10.0'target 'application_name' do use_frameworks!
pod 'GoogleMaps' pod 'Alamofire', '~> 4.4.0' pod 'PusherSwift', '~> 4.1.0'end
⚠️ Обязательно замените
application_name
с названием вашей программы.
Выполните следующую команду, чтобы начать установку пакетов, указанных в нашем Podfile
:
$ pod install
После завершения установки откройте файл *.xcworkspace
файл, который был добавлен в корень вашего каталога программы. Это должно запустить Xcode.
Настройка нашего симулятора Node.js
Прежде чем вернуться к нашей программе iOS, нам нужно создать простую программу Node.js. Это приложение будет отправлять события с данными в Pusher. Данные, отправленные в Pusher, будут смоделированы GPS-координатами. Когда наше приложение iOS получает данные события от Pusher, оно обновит маркер карты до новых координат.
Создайте новый каталог, который будет содержать нашу программу Node.js. Откройте свой терминал и cd
в каталог программы Node.js. В этом каталоге создайте новый package.json
файл. Откройте этот файл и вставьте файл JSON ниже:
{ "main": "index.js", "dependencies": { "body-parser": "^1.16.0", "express": "^4.14.1", "pusher": "^1.5.1" } }
Теперь выполните указанную ниже команду, чтобы установить пакеты NPM, указанные как зависимости:
$ npm run install
Создайте новый index.js
файл в каталоге и вставьте следующий код в файл:
// // Load the required libraries // let Pusher = require('pusher'); let express = require('express'); let bodyParser = require('body-parser'); // // initialize express and pusher // let app = express(); let pusher = new Pusher(require('./config.js')); // // Middlewares // app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false }));
// // Generates 20 simulated GPS coords and sends to Pusher // app.post('/simulate', (req, res, next) => { let loopCount = 0; let operator = 0.001000 let longitude = parseFloat(req.body.longitude) let latitude = parseFloat(req.body.latitude) let sendToPusher = setInterval(() => { loopCount++; // Calculate new coordinates and round to 6 decimal places... longitude = parseFloat((longitude + operator).toFixed(7)) latitude = parseFloat((latitude - operator).toFixed(7)) // Send to pusher pusher.trigger('mapCoordinates', 'update', {longitude, latitude}) if (loopCount === 20) { clearInterval(sendToPusher) } }, 2000); res.json({success: 200}) })
// // Index // app.get('/', (req, res) => { res.json("It works!"); });
// // Error Handling // app.use((req, res, next) => { let err = new Error('Not Found'); err.status = 404; next(err); });
// // Serve app // app.listen(4000, function() { console.log('App listening on port 4000!')});
Вышеприведенный код является простым приложением Express. Мы инициализировали Express app
и pusher
экземпляр. В /simulate
маршрута выполняем цикл с интервалом в 2 секунды и разрываем цикл после 20-го прогона. Каждый раз, когда цикл выполняется, новые координаты GPS генерируются и отправляются в Pusher.
Создайте новый config.js
файл и вставьте в него следующий код:
module.exports = { appId: 'PUSHER_APP_ID', key: 'PUSHER_APP_KEY', secret: 'PUSHER_APP_SECRET', cluster: 'PUSHER_APP_CLUSTER', };
Замените значение *PUSHER_APP_ID*
, *PUSHER_APP_KEY*
, PUSHER_APP_SECRET
и PUSHER_APP_CLUSTER
со значениями на информационной панели Pusher. Наша программа Node.js теперь готова моделировать координаты GPS при запуске программы.
Теперь, когда мы закончили создание Node.js, мы можем вернуться к созданию iOS.
Создание представлений нашей карты в реальном времени в Xcode
Снова откройте Xcode с нашим проектом и откройте файл Main.storyboard
файл. В ViewController
мы добавим а UIView
и в этом UIView
мы добавим кнопку имитации. Что-то вроде этого:

Создайте @IBAction
от кнопки до ViewController
. Для этого нажмите «Показать редактор помощника» в правом верхнем углу набора инструментов Xcode. Это разделит экран на раскадровку и редактор кода. Теперь ctrl
и перетащите от кнопки к редактору кода, чтобы создать @IBAction
. Мы назовем метод simulateMovement
.

Далее нажмите кнопку «Показать стандартный редактор» на панели инструментов Xcode, чтобы закрыть разделенный экран и отобразить только Main.storyboard
. Добавьте другое UIView
начиная с нижней части последнего UIView
к нижней части экрана. В этом виде будет отображаться карта.
Установите UIView
‘s пользовательского класса в «Инспекторе идентификации». GMSMapView
. Теперь нажмите «Показать редактор помощника» в правом верхнем углу набора инструментов Xcode. ctrl
и перетащить из UIView
к редактору кода. Создайте @IBOutlet
и назовите его mapView
.
Нажмите кнопку «Показать стандартный редактор» на панели инструментов Xcode, чтобы закрыть разделенное представление. Откройте ViewController
файл и замените содержимое кодом ниже:
// // Import libraries // import UIKit import PusherSwift import Alamofire import GoogleMaps
// // View controller class // class ViewController: UIViewController, GMSMapViewDelegate { // Marker on the map var locationMarker: GMSMarker!
// Default starting coordinates var longitude = -122.088426 var latitude = 37.388064
// Pusher var pusher: Pusher!
// Map view @IBOutlet weak var mapView: GMSMapView!
// // Fires automatically when the view is loaded // override func viewDidLoad() { super.viewDidLoad()
// // Create a GMSCameraPosition that tells the map to display the coordinate // at zoom level 15. // let camera = GMSCameraPosition.camera(withLatitude:latitude, longitude:longitude, zoom:15.0) mapView.camera = camera mapView.delegate = self
// // Creates a marker in the center of the map. // locationMarker = GMSMarker(position: CLLocationCoordinate2D(latitude: latitude, longitude: longitude)) locationMarker.map = mapView
// // Connect to pusher and listen for events // listenForCoordUpdates() }
// // Send a request to the API to simulate GPS coords // @IBAction func simulateMovement(_ sender: Any) { let parameters: Parameters = ["longitude":longitude, "latitude": latitude]
Alamofire.request(" method: .post, parameters: parameters).validate().responseJSON { (response) in switch response.result { case .success(_): print("Simulating...") case .failure(let error): print(error) } } }
// // Connect to pusher and listen for events // private func listenForCoordUpdates() { // Instantiate Pusher pusher = Pusher(key: "PUSHER_APP_KEY", options: PusherClientOptions(host: .cluster("PUSHER_APP_CLUSTER")))
// Subscribe to a Pusher channel let channel = pusher.subscribe("mapCoordinates")
// // Listener and callback for the "update" event on the "mapCoordinates" // channel on Pusher // channel.bind(eventName: "update", callback: { (data: Any?) -> Void in if let data = data as? [String: AnyObject] { self.longitude = data["longitude"] as! Double self.latitude = data["latitude"] as! Double
// // Update marker position using data from Pusher // self.locationMarker.position = CLLocationCoordinate2D(latitude: self.latitude, longitude: self.longitude) self.mapView.camera = GMSCameraPosition.camera(withTarget: self.locationMarker.position, zoom: 15.0) } })
// Connect to pusher pusher.connect() } }
В вышеприведенный класс контроллера мы импортируем все необходимые библиотеки. Затем мы создаем несколько свойств класса. В viewDidLoad
метод, мы устанавливаем координаты на mapView
а также добавить locationMarker
к нему.
Таким же методом мы совершаем вызов к listenForCoordUpdates()
. В listenForCoordUpdates
метод мы создаем соединение с Pusher и прослушиваем update
событие на mapCoordinates
канал.
Когда update
инициируется событие, обратный вызов принимает новые координаты и обновляет locationMarker
с ними. Помните, что вам нужно изменить PUSHER_APP_KEY
и PUSHER_APP_CLUSTER
к фактическим значениям, приведенным для вашей программы Pusher.
В simulateMovement
метод, мы просто посылаем запрос на наш локальный веб-сервер (приложение Node.js, которое мы создали ранее). Запрос указывает программе Node.js сгенерировать несколько GPS-координатов.
? URL-адрес конечной точки, который мы используем ( является локальным веб-сервером. Это означает, что вам нужно будет изменить URL-адрес конечной точки при создании для реальных случаев).
Настройки Google Maps для iOS
Нам нужно будет настроить Google Maps iOS SDK для работы с нашим приложением. Сначала создайте ключ Google iOS SDK, а затем, когда у вас есть ключ API, откройте файл AppDelegate.swift
файл в Xcode.
В классе найдите класс ниже:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. return true }
и замените его этим:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { GMSServices.provideAPIKey("GOOGLE_IOS_API_KEY") return true }
? Вам нужно заменить G
OOGLE_IOS_API_KEY
с ключом, полученным при создании ключа API Google iOS.
Найдите в верхней части того же файла import UIKit
и добавьте под ним следующее:
import GoogleMaps
На этом мы завершили настройки Карты Google для работы на iOS.
Тестирование нашей карты iOS в реальном времени
Чтобы протестировать наше приложение, нам нужно запустить приложение Node.js, указать iOS разрешить подключение к локальному веб-серверу, а затем запустить наше приложение iOS.
Чтобы запустить программу Node.js, cd
в каталог программы Node.js с помощью терминала и выполните команду ниже, чтобы запустить программу Node:
$ node index.js
Теперь, прежде чем запустить наше приложение, нам нужно внести последние изменения, чтобы наше приложение iOS могло подключиться к нашему localhost
бэкенд. Откройте info.plist
файл в Xcode и внесите следующие изменения:

Это изменение позволит нашей программе подключиться к локальному хосту. Чтобы было ясно, этот шаг не пригодится в производственных средах.
Теперь создайте свою программу. Вы должны увидеть, что iOS теперь отображает карту и маркер на карте. Нажатие кнопки имитации попадает на конечную точку, которая, в свою очередь, посылает новые координаты Pusher. Наш слушатель отслеживает событие и обновляет locationMarker
тем самым перемещая наш маркер.
Вывод
В этой статье мы увидели, как можно использовать Pusher и Swift для создания карты в реальном времени на iOS. Надеюсь, вы узнали несколько вещей о том, как создавать приложения iOS в реальном времени. Если у вас есть вопросы или предложения, оставьте комментарий ниже.
Эта публикация была впервые опубликована в Pusher.