GMS Mapview мерцает, перезагружается и падает при обновлении координат - PullRequest
0 голосов
/ 11 февраля 2019

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

То, что я пытаюсь сделать, это вытащить координаты из Firebase, а затем сбросить два «булавки» или маркера в GMSMapview.У меня есть UIView, классифицированный как GMSMapview и подключенный через IBOutlet.Поэтому, когда ViewController загружает Google Maps, MapView находится в UIView.То, что я пытаюсь сделать, это иметь «контакт», где находится «драйвер», и второй контакт, где «мое» местоположение.Я хочу сделать так, чтобы карта «увеличивала масштаб и следовала» за драйвером, пока он не прибудет в мое местоположение, аналогично Uber.

Я пробовал сотни различных типов комбинаций кода и нашел здесь статьи на StackOverflowчто я следовал, но те не работали.Мне удалось отобразить контакты (зеленый - это драйвер, красный - то, куда он направляется), и когда я вошел в Firebase и изменил одну из координат, экран «прыгнул» или мерцал очень плохо.Продолжая исследование, я прочитал, что для реализации этой концепции (и для отображения всех «машин» в качестве маркеров на GMS MapView, как это делает Uber, в другом ViewController), мне нужно поместить свои координаты в массив, а затем выполнить циклмодель, содержащая структуру с переменными.Как только я это сделал, «мерцание» прекратилось, но затем весь контроллер представления продолжал перезагружаться с нуля (как будто ViewController был только что открыт в первый раз) каждый раз, когда я обновлял координату.Иногда я делал широту, а иногда - долготу, но это не имело значения.Очевидно, что поскольку я обновлял Firebase вручную, я не мог одновременно использовать оба значения.

Статьи, которые я нашел в StackOverflow, казались очень многообещающими, и я считаю, что я на правильном пути, за исключением того, что реализовал некоторые из них.Рекомендованный код от Google, и вот, теперь я получаю нулевой сбой (указанный в моем коде ниже).Этот сбой происходит после того, как я захожу в Firebase и вручную обновляю координаты (либо широты, либо долготы).

После почти месяца попыток настроить и заставить этот код работать, я ищу некоторые рекомендации относительногде я ошибся с моим кодом.Я использую последние PODS для GoogleMaps и Firebase.В итоге, я ищу способ перемещения маркера GMS, пока обновляются координаты, в реальном времени в Firebase, а также увеличение масштаба карты по мере приближения к «моему местоположению».

Вот статьиЯ исследовал и проследил: Проблема мерцания в представлении карты GMS

Как переместить маркер вместе с перемещением карты Google в iOS?

Здесьмой код:

import UIKit
import CoreLocation
import CoreData
import Firebase
import FirebaseDatabase
import FirebaseAuth
import GoogleMaps
import GooglePlaces
import GooglePlacesPicker
import Alamofire
import SwiftyJSON

class SOPOST: UIViewController, CLLocationManagerDelegate, GMSMapViewDelegate, Alertable {

    @IBOutlet weak var connectedMapView: GMSMapView!
    @IBOutlet weak var driverInfoView: UIView!

    let currentUserId = Auth.auth().currentUser?.uid

    var markers = [] as NSArray

    var locationManager = CLLocationManager()
    var placesClient: GMSPlacesClient!
    var zoomLevel: Float = 12.0
    var likelyPlaces: [GMSPlace] = []
    var selectedPlace: GMSPlace?

    var custlat: CLLocationDegrees?
    var custlong: CLLocationDegrees?
    var driverlat: CLLocationDegrees?
    var driverlong: CLLocationDegrees?
    var destlat: CLLocationDegrees?
    var destlong: CLLocationDegrees?

    var location: CLLocation?

    var destinationMarker = GMSMarker()


    var currentCoordAddress: CLLocationCoordinate2D?
    var destinationCoordAddress: CLLocationCoordinate2D?
    var driverCoordAddress: CLLocationCoordinate2D?


    override func viewDidLoad() {
        super.viewDidLoad()

        connectedMapView.delegate = self
        DispatchQueue.main.async {
            DataService.instance.REF_TRIPS.observe(.value, with: { (snapshot) in
                if let findDriverSnapshot = snapshot.children.allObjects as? [DataSnapshot] {
                    for driver in findDriverSnapshot {
                        if driver.childSnapshot(forPath: "passengerKey").value as? String == self.currentUserId! {
                            let acceptanceStatus = driver.childSnapshot(forPath: "tripIsAccepted").value as! Bool
                            if acceptanceStatus == true {
                                if let observeAcceptDict = driver.value as? Dictionary<String, AnyObject> {
                                    let pickupCoordinateArray = observeAcceptDict["pickupCoordinate"] as! NSArray
                                    self.custlat = pickupCoordinateArray[0] as? CLLocationDegrees
                                    self.custlong = pickupCoordinateArray[1] as? CLLocationDegrees

                                    let driverCoordinateArray = observeAcceptDict["driverCoordinate"] as! NSArray
                                    self.markers = observeAcceptDict["driverCoordinate"] as! NSArray
                                    self.driverlat = driverCoordinateArray[0] as? CLLocationDegrees
                                    self.driverlong = driverCoordinateArray[1] as? CLLocationDegrees
                                    let prepareLocation = CLLocation(latitude: self.driverlat!, longitude: self.driverlong!)
                                    self.location = prepareLocation
                                    let destCoordinateArray = observeAcceptDict["destinationCoordinate"] as! NSArray
                                    self.destlat = destCoordinateArray[0] as? CLLocationDegrees
                                    self.destlong = destCoordinateArray[1] as? CLLocationDegrees
                                    self.currentCoordAddress = CLLocationCoordinate2DMake(self.custlat!, self.custlong!)
                                    self.destinationCoordAddress = CLLocationCoordinate2DMake(self.destlat!, self.destlong!)
                                    self.driverCoordAddress = CLLocationCoordinate2DMake(self.driverlat!, self.driverlong!)
                                    CATransaction.begin()
                                    CATransaction.setAnimationDuration(1.0)
                                    self.destinationMarker.position = CLLocationCoordinate2D(latitude: (self.markers[0] as? CLLocationDegrees)!, longitude: (self.markers[1] as? CLLocationDegrees)!)
                                    self.connectedMapView.camera = GMSCameraPosition.camera(withTarget: self.destinationMarker.position, zoom: 12.0)

                                    self.destinationMarker.icon = GMSMarker.markerImage(with: UIColor.green)
                                    self.destinationMarker.map = self.connectedMapView
                                    self.destinationMarker.tracksViewChanges = false
                                    CATransaction.commit()

                                    let customerdestmarker = GMSMarker()
                                    customerdestmarker.position = CLLocationCoordinate2D(latitude: self.custlat!, longitude: self.custlong!)
                                    customerdestmarker.icon = GMSMarker.markerImage(with: UIColor.red)
                                    customerdestmarker.map = self.connectedMapView
                                    customerdestmarker.tracksViewChanges = false

                                }
                            }
                        }
                    }
                }
            })

        }

    }

    func updateLocationoordinates(coordinates:CLLocationCoordinate2D) {
        if destinationMarker == nil
        {
            destinationMarker = GMSMarker()
            destinationMarker.position = coordinates
            let image = UIImage(named:"destinationmarker")
            destinationMarker.icon = image
            destinationMarker.map =  self.connectedMapView
            destinationMarker.appearAnimation = GMSMarkerAnimation.pop
        }
        else
        {
            CATransaction.begin()
            CATransaction.setAnimationDuration(1.0)
            destinationMarker.position =  coordinates
            CATransaction.commit()
        }
    }

    func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
        self.destinationMarker = GMSMarker(position: self.location!.coordinate)  // <----CRASHES HERE: Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
        destinationMarker.position = position.target
        let destinationLocation = CLLocation(latitude: destinationMarker.position.latitude, longitude: destinationMarker.position.longitude)
        let destinationCoordinate = destinationLocation.coordinate
        updateLocationoordinates(coordinates: destinationCoordinate)
    }

}
...