Firebaseから取得したデータをもとに地図上に複数のmarkerを表示したい
コメントのような文章を投稿し、それを地図上に表示させる形式のSNSアプリを開発しています。
Googlemap APIとfirebaseのRealtime Databaseを利用しています。
現状、ログイン、投稿画面、地図の表示は済み、地図上にコンテンツを一つmarkerとして表示させるところまでは進みましたが、地図上に複数のコンテンツを表示させる方法がわからず困っております。
何卒ご教示頂ければ幸いです。
下記クラスでfirebase側から投稿データを取得しています
PostData.swift
class PostData: NSObject {
var id: String?
var userName: String?
var text: String?
var latitude: String?
var longitude: String?
init(snapshot: DataSnapshot, myId: String) {
self.id = snapshot.key
let valueDictionary = snapshot.value as! [String: AnyObject]
self.latitude = valueDictionary["latitude"] as? String
self.longitude = valueDictionary["longitude"] as? String
self.text = valueDictionary["text"] as? String
self.userName = valueDictionary["userName"] as? String
}
}
下記はメインの地図画面クラスです
Map_ViewController.swift
class Map_ViewController: UIViewController, CLLocationManagerDelegate, GMSMapViewDelegate{
var mapManager: CLLocationManager = CLLocationManager()
var latitude: CLLocationDegrees!
var longitude: CLLocationDegrees!
var gmaps: GMSMapView!
var postArray: [PostData] = []
var observing = false
var marker = GMSMarker()
override func viewDidLoad() {
super.viewDidLoad()
mapManager = CLLocationManager()
latitude = CLLocationDegrees()
longitude = CLLocationDegrees()
mapManager.delegate = self
mapManager.requestWhenInUseAuthorization()
mapManager.requestAlwaysAuthorization()
mapManager.desiredAccuracy = kCLLocationAccuracyBest
mapManager.distanceFilter = 1000
mapManager.startUpdatingLocation()
gmaps = GMSMapView(frame: CGRect(x:0, y:0, width:self.view.bounds.width, height:self.view.bounds.width))
self.view.addSubview(gmaps)
gmaps.isMyLocationEnabled = true
gmaps.settings.compassButton = true
self.view = gmaps
gmaps.delegate = self
if Auth.auth().currentUser != nil {
if self.observing == false {
let postsRef = Database.database().reference().child("messages")
postsRef.observe(.childAdded, with: { snapshot in
if let uid = Auth.auth().currentUser?.uid {
let postData = PostData(snapshot: snapshot, myId: uid)
self.postArray.insert(postData, at: 0)
print("\(self.postArray)")
for element in self.postArray{
self.makeMarker(postData: element)
}
}
})
}
}
}
func makeMarker(postData: PostData) -> GMSMarker {
let latitude = Double(postData.latitude!)
let longitude = Double(postData.longitude!)
marker.position = CLLocationCoordinate2D(latitude: latitude!, longitude: longitude!)
marker.title = "\(postData.text!)"
marker.tracksInfoWindowChanges = true //情報ウィンドウを自動的に更新するように設定する
marker.appearAnimation = GMSMarkerAnimation.pop //マーカーの表示にアニメーションをつける
gmaps.selectedMarker = marker //デフォルトで情報ウィンドウを表示
marker.map = self.gmaps
return marker
}
//現在地の読み込み完了時に呼ばれるメソッド
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation:CLLocation = locations[0] as CLLocation
latitude = userLocation.coordinate.latitude
longitude = userLocation.coordinate.longitude
let now :GMSCameraPosition = GMSCameraPosition.camera(withLatitude: latitude,longitude:longitude,zoom:14)
gmaps.camera = now
}
}
ログを見るとfor文でアクセスしている配列postArray内にデータは引いてこれているので、その要素すべてにアクセスはできているとは思うのですが、makeMarkerメソッドがその要素ひとつぶんにしかアクセスできておらずmarkerが一つしか出せない状況です。(説明が悪くすみません)
forEach文に変えてみたりなどは試しましたが、結局1つしかmarkerを出せずといった感じです。
以上、アプローチの見直しも含めてご教示頂けますと幸いです。