集群/去集群后谷歌 iOS 集群管理器“marker.userData”NIL

Posted

技术标签:

【中文标题】集群/去集群后谷歌 iOS 集群管理器“marker.userData”NIL【英文标题】:Google iOS Cluster Manager "marker.userData" NIL after Cluster/de-Cluster 【发布时间】:2021-03-04 05:37:39 【问题描述】:

我正在尝试升级我的 ios 应用程序以使用 Google Map Clustering。 该应用使用“添加的子项”从 Firebase 数据库加载超过 19,000 个标记,我使用“marker.userData”为每个标记分配一个 ID,如下所示:

        dbRef = Database.database().reference()
        let markerRef = dbRef.child("markers")
        //Load all Markers when app starts
        //child added returns all markers, then Listens for new additions
        markerRef.observe(.childAdded, with:  [self] snapshot in
            markerCount = markerCount+1
            let markerKey = snapshot.key
            let value = snapshot.value as? NSDictionary
            let x = value?["x"] as? Double
            let y = value?["y"] as? Double
            let v = value?["v"] as? Bool
            
            if v == true 
                //print("adding Verifed icon")
                let position = CLLocationCoordinate2D(latitude: y ?? 0.0 , longitude: x ?? 0.0)
                let marker = GMSMarker(position: position)
                marker.icon = UIImage(named: "VerifiedPin")
                marker.userData = markerKey
                self.markerArray.append(marker)
                //print("marker Array: ", self.markerArray)
                clusterManager.add(marker)
            else
                //print("adding Unverifed icon")
                let position = CLLocationCoordinate2D(latitude: y ?? 0.0 , longitude: x ?? 0.0)
                let marker = GMSMarker(position: position)
                marker.icon = UIImage(named: "UnverifiedPin")
                marker.userData = markerKey
                self.markerArray.append(marker)
                //print("marker Array: ", self.markerArray)
                clusterManager.add(marker)
            
            if(markerCount >= numMarkers 
                self.clusterManager.cluster()
            )
        )  (error:Error) in
            print("startObservingDB error: ", error.localizedDescription)
            self.noDatabaseConnection()
        

当用户点击标记图标“GMSMapView, didTap marker: GMSMarker”时,如果“marker.userData”不是GMUCluster,“marker.userData”应该包含标记添加到集群时分配的ID .这在不使用集群时可以正常工作。

    // MARK: - GMSMapViewDelegate
    //Detect when user taps on a specific icon and display the infoBox
    func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool 
        if marker.userData is GMUCluster 
            // center the map on tapped marker
            viewMap.animate(toLocation: marker.position)
            // zoom in on tapped cluster
            viewMap.animate(toZoom: viewMap.camera.zoom + 1)
            print("Did tap cluster")
            return true
        
        tappedMarker = marker
        let markerKey = marker.userData as! String
        print("Did tap marker w/key: ", markerKey)

        self.dbRef = Database.database().reference()
        self.dbRef.child(markerKey).observeSingleEvent(of: .value, with:  (snapshot: DataSnapshot) in
            let areaObj = Area(snapshot: snapshot)
            let table = areaObj
            print("Table info: ", table)
            self.tableMarker = markerKey
            print("this is table \(markerKey)")
            self.currentTable = table
            print (table.verified)
            self.lblVerified.isHidden = !table.verified
            
            table.itemRef?.child("verified").observe(.value, with:  (snapshot) in
                if let bVerified = snapshot.value as? Bool 
                    table.verified = bVerified
                    self.lblVerified.isHidden = !table.verified
                
            )
            print("source = \(String(describing: table.source))")
            print("imported = \(String(describing: table.imported))")
            if (table.source != nil) 
                self.btnVerify.isHidden = true
             else 
                self.btnVerify.isHidden = table.verified
            
            self.viewPicDetail.isHidden = false
            let formatter = DateFormatter()
            if table.lastUpdated == 0.0 
                let defaultDate = "06/30/2018"
                formatter.dateFormat = "MM/dd/yyyy"
                let date = formatter.date(from: defaultDate)
                formatter.locale = Locale(identifier: Locale.preferredLanguages.first!)
                formatter.dateStyle = .short
                self.lblLastUpdate.text = self.lastUpdateText+"\(formatter.string(from: date!))"
             else 
                let date = Date(timeIntervalSince1970: table.lastUpdated)
                formatter.locale = Locale(identifier: Locale.preferredLanguages.first!)
                formatter.dateStyle = .short
                self.lblLastUpdate.text = self.lastUpdateText+"\(formatter.string(from: date))"
            
            self.refreshDescription()
            self.observeCommentsRatings()
        )
        return false
    

当地图首次显示时,点击标记可以正常工作,并且“marker.userData”包含正确的 ID。当地图被缩小时,标记被聚集在一起,随后的放大显示各个标记。在此操作后点击标记会导致 致命错误:Unexpectedly found nil while unwrapping an Optional 这意味着“marker.userData”的值为“nil”。

集群管理器似乎在对标记进行聚类然后“取消聚类”它们之后破坏了“marker.userData”。

有其他人看到这个问题还是我做错了什么?

【问题讨论】:

这里提到的解决方法已经解决了这个问题:github.com/googlemaps/google-maps-ios-utils/issues/349 【参考方案1】:

我在 GitHub 库问题跟踪器上报告了这个问题。 Google 开发团队重现了该问题,修复了 GMUDefaultClusterRenderer.m 并发布了 google-maps-ios-utils 库的 3.4.2 版。更多信息请访问:

https://github.com/googlemaps/google-maps-ios-utils/issues/349

非常感谢开发团队解决了这个问题并快速发布了库的更新版本。

【讨论】:

以上是关于集群/去集群后谷歌 iOS 集群管理器“marker.userData”NIL的主要内容,如果未能解决你的问题,请参考以下文章

在 android 谷歌地图中更改集群管理器项目图标

仅在谷歌地图上呈现可见集群项目的最佳方式

删除旧地图标记并在集群管理器中加载新标记

Spark集群管理器介绍

Spark的集群管理器

Databricks 中使用的集群管理器是啥?如何更改 Databricks 集群中的执行程序数量?