removeMarker does not work on iOS due to overly large marker `id` integer
patrick-entinux opened this issue · comments
Describe the bug
On iOS, Marker ID, which comes from hash value, may be a really large number like 3850296949834213376
. This is too large to express safely as a JavaScript number
and suffers data loss when passed through the capacitor bridge.
For didTap
event, this is fine, because the data loss is the same as in the original addMarker function, so the marker can still be linked up by ID on the JavaScript side. However, for removeMarker method, as far as I can tell, it is basically impossible to use because our id
in JavaScript needs to match the original id
in the hashMap
perfectly.
To Reproduce
(1) Run some code like below:
const result: { marker: { id: number } } =
await CapacitorGoogleMaps.addMarker({
latitude: marker.latitude,
longitude: marker.longitude,
title: marker.title,
});
await CapacitorGoogleMaps.removeMarker({ id: result.marker.id });
(2) Observe that the marker is not deleted
Expected behavior
The marker should be deleted.
Screenshots
Demonstration of MAX_SAFE_INTEGER in JavaScript and data loss between input and output for an integer like 3850296949834213376
:
Demonstration of input value to removeMarker
function (as parsed inside the native code side) compared to the list of all values in the hashMap
:
Additional context
One super basic workaround could be to pass marker ids as string, starting with the prefix m
, similar to the Android side of the plugin (which appears to use a string starting with m
):
var hashMap = [String : GMSMarker]();
...
let id = "m\(marker.hash.hashValue)"
// get auto-generated id of the just added marker,
// put this marker into a hashmap with the corresponding id,
// so we can retrieve the marker by id later on
self.hashMap[id] = marker;
NSLog("addMarker \(id)")
call.resolve([
"markerAdded": true,
// get marker specific values
"marker": [
"id": id
]
])
...
public func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
self.notifyListeners("didTap", data: ["result": [
"coordinates": [
"latitude": marker.position.latitude,
"longitude": marker.position.longitude
],
"id": "m\(marker.hash.hashValue)",
"title": marker.title ?? "",
"snippet": marker.snippet ?? "",
"metadata": marker.userData
]])
return false
}
We've just released a (pretty stable) beta for version 2 of this plugin under the name @capacitor-community/google-maps
.
It features a more complete and consistent API. Also the map can finally be rendered behind the webview in this new version.
Extensive documentation for v2 can be found here: https://capacitor-community.github.io/google-maps/
Since version 1 lacked a lot of (basic) features, did not have good coding practices, had a poor API and it is not recommended to use it anymore, we've dropped support for it. Therefore I will close this issue. We believe version 2 offers a better Developer Experience and is a much better fit for anyones use case.