Search code examples
iosswiftgoogle-maps-sdk-ios

Ios how to pass google map userData to next view


I'm trying to pass google map's userData to next view when user tapped custom info window.

first I created model object like so.

import UIKit
import Firebase

    struct Team {

        var key: String
        var teamName: String
        var league: String
        var lat: Double
        var lng: Double

        init(snapshot: DataSnapshot) {

            self.key = snapshot.key
            self.teamName = (snapshot.value as! NSDictionary)["teamName"] as? String
            self.league = (snapshot.value as! NSDictionary)["league"] as? String ?? ""
            self.lat = (snapshot.value as! NSDictionary)["lat"] as? Double ?? 0
            self.lng = (snapshot.value as! NSDictionary)["lng"] as? Double ?? 0
        }
    }

I fetched database and put userData like so

var teams = [Team?]()

    func fetchTeams(){

            let teamRef = Database.database().reference().child("teams")
            teamRef.observe(.value, with: { (snapshot) in
                var result = [Team]()

                for child in snapshot.children {
                    let child = Team(snapshot: child as! DataSnapshot)
                    result.append(child)
                    self.teams = result
                }

                for team in self.teams {
                    guard let lat = team?.lat else { return }
                    guard let lng = team?.lng else { return }
                    let marker: GMSMarker = GMSMarker()
                    marker.position = CLLocationCoordinate2DMake(lat, lng)
                    marker.map = self.mapView
                    marker.userData = team
                }

            }, withCancel: nil)
        }

this func works perfectly so I guess userData has its property correctly.

func mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView? {
            let infoWindow = Bundle.main.loadNibNamed("Marker", owner: self, options: nil)?.first as! MarkerView

            infoWindow.teamLabel.text = (marker.userData as! Team).teamName

            return infoWindow
        }


func mapView(_ mapView: GMSMapView, didTapInfoWindowOf marker: GMSMarker) {
        self.performSegue(withIdentifier: cellId, sender: self)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == cellId {
            let next: NextViewController = segue.destination as! NextViewController
            let marker = GMSMarker()
            next.team = marker.userData as? Team
        }
    }

I implemented like above to pass data to NextViewController. it worked fine till performSegue but next.team is nil. Does anyone know why? Thank you in advance!


Solution

  • You are having that issue because you are creating an empty GMSMarker and of course this empty GMSMarker don't have any userData, you have to pass the selected GMSMarker as parameter in the performSegue, specifically in the sender parameter, and cast as Team and pass it to your NextViewController

    func mapView(_ mapView: GMSMapView, didTapInfoWindowOf marker: GMSMarker) {
            self.performSegue(withIdentifier: cellId, sender: marker.userData)
        }
    
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if segue.identifier == cellId {
                let next: NextViewController = segue.destination as! NextViewController
                if let teamData = sender as? Team{
                   next.team = teamData
                   debugPrint("teamData is fine")
                }
                debugPrint("segue identifier is correct")
            }
        }