Search code examples
iosswiftfirebasefirebase-realtime-databasemkmapview

Place multiple markers on MKMapView from Firebase Database


I'm creating an iOS app that uses Apple Maps to display markers for Garage/Yard Sales in the local area. So far I've been able to figure out how to place one marker on Apple Maps from the Firebase Database, but I'm not sure how to do it with multiple markers. I've done similar tasks using cells to display different content in a UITableView from Firebase Database but this is my first time doing it map-wise. I was reading an article here that showed how it was possible with JSON data, but due to the fact the marker information will be live, it wouldn't be possible that way for my app. What would be the best way to add multiple markers to a MKMapView?

Snippet from ViewController (Only setup for one marker)

Database.database().reference().child("posts").observeSingleEvent(of: .value, with: { (snapshot) in
        if let dictionary = snapshot.value as? [String: AnyObject] {
            let artwork = Artwork(title: dictionary["title"] as! String,
                                  locationName: dictionary["location"] as! String,
                                  discipline: dictionary["category"] as! String,
                                  coordinate: CLLocationCoordinate2D(latitude: dictionary["lat"] as! Double, longitude: dictionary["long"] as! Double))
            self.mapView.addAnnotation(artwork)
        }
    })

Artwork.swift

class Artwork: NSObject, MKAnnotation {
    let title: String?
    let locationName: String
    let discipline: String
    let coordinate: CLLocationCoordinate2D

    init(title: String, locationName: String, discipline: String, coordinate: CLLocationCoordinate2D) {
        self.title = title
        self.locationName = locationName
        self.discipline = discipline
        self.coordinate = coordinate

        super.init()
    }

    var subtitle: String? {
        return locationName
    }
}

Solution

  • I was able to figure out a way to this thanks to the link @kosuke-ogawa posted.

    Snippet within ViewController.swift

    override func viewDidLoad() {
            super.viewDidLoad()    
            let ref = Database.database().reference()
            let postsRef = ref.child("posts")
            postsRef.observeSingleEvent(of: .value, with: { (snapshot) in
                for snap in snapshot.children {
                    let postSnap = snap as! DataSnapshot
                    if let dict = postSnap.value as? [String:AnyObject] {
                        let title = dict["title"] as! String
                        let locationName = dict["location"] as! String
                        let discipline = dict["category"] as! String
                        let coordinate = CLLocationCoordinate2D(latitude: dict["lat"] as! Double, longitude: dict["long"] as! Double)
                        let artwork = Artwork(title: title, locationName: locationName, discipline: discipline, coordinate: coordinate)
                        self.mapView.addAnnotation(artwork)
                    }
                }
            })
        }
    

    If there is a cleaner way to do this feel free to edit my code to help others in the future.