Как построить карту в реальном времени с помощью Swift

1656621373 kak postroit kartu v realnom vremeni s pomoshhyu swift

автор Нео Игадаро

IxlZRMwTCK2070izDrv3rY52ZZjzcLrGtxPp
Фото NASA на Unsplash

Карты реального времени очень популярны в наше время. Особенно сейчас, когда существует много транспортных служб по требованию, таких как Uber и Lyft, имеющие отчеты о местонахождении в реальном времени. В этой статье мы узнаем, как создать карту реального времени на iOS с помощью Pusher.

Прежде чем мы продолжим, вам нужно убедиться, что вы отвечаете всем нижеприведенным требованиям.

  • MacBook (Xcode работает только на Mac).
  • Xcode установлен на вашем автомобиле.
  • Знание JavaScript (Node.js).
  • Знание Swift и использование Xcode. Вы можете начать здесь.
  • NPM и Node.js установлены локально.
  • Менеджер пакетов Cocoapods установлен локально.
  • Ключ API Google iOS. См. инструкции по получению ключа.
  • Программа Pusher. Создайте его здесь.

Для выполнения этого руководства необходимо базовое понимание Swift и Node.js.

Предположим, что у вас есть все требования, начнём. Это экранная запись того, что мы будем строить:

oNEt5czqqZUmTL5r6SvWAjv2QBSnWgYEr8RT

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

Настройка нашего приложения для iOS

Запустите Xcode и создайте новый проект «Single-app». Вы можете называть проект как угодно.

SykobSVDuoF5VSM3PZeNvC4sISPAbkoYUwIb

При создании проекта закройте 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 мы добавим кнопку имитации. Что-то вроде этого:

rOVmC-h3c2R2xCeeuPcTlp8g7fG5Yr-tWJl6

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

sirx-Tu8WaaGQUQVz4IKvuTdFlhZELT2qM0F

Далее нажмите кнопку «Показать стандартный редактор» на панели инструментов 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 }

? Вам нужно заменить GOOGLE_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 и внесите следующие изменения:

k0V9gHDnWihDnOigSrwEOias6xFVD0Di-5Td

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

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

Вывод

В этой статье мы увидели, как можно использовать Pusher и Swift для создания карты в реальном времени на iOS. Надеюсь, вы узнали несколько вещей о том, как создавать приложения iOS в реальном времени. Если у вас есть вопросы или предложения, оставьте комментарий ниже.

Эта публикация была впервые опубликована в Pusher.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *