Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Will this library work with KMP and Compose for iOS? #72

Open
realityexpander opened this issue Aug 18, 2023 · 7 comments
Open

Will this library work with KMP and Compose for iOS? #72

realityexpander opened this issue Aug 18, 2023 · 7 comments

Comments

@realityexpander
Copy link

No description provided.

@sdzshn3
Copy link

sdzshn3 commented Sep 25, 2023

Doesn't seem like

@realityexpander
Copy link
Author

What is the suggested alternative?

@sdzshn3
Copy link

sdzshn3 commented Sep 25, 2023

I have done something like this

@Composable
expect fun GoogleMaps(
    modifier: Modifier,
    markers: List<MapMarker>? = null,
    cameraPosition: CameraPosition? = null,
    cameraPositionLatLongBounds: CameraPositionLatLongBounds? = null,
    polyLine: List<LatLong>? = null
)
@Composable
actual fun GoogleMaps(
    modifier: Modifier,
    markers: List<MapMarker>?,
    cameraPosition: CameraPosition?,
    cameraPositionLatLongBounds: CameraPositionLatLongBounds?,
    polyLine: List<LatLong>?
) {

    val cameraPositionState = rememberCameraPositionState()

    LaunchedEffect(cameraPosition) {
        cameraPosition?.let {
            cameraPositionState.animate(
                CameraUpdateFactory.newLatLngZoom(
                    LatLng(
                        it.latLong.latitude,
                        it.latLong.longitude
                    ), it.zoom
                )
            )
        }
    }

    LaunchedEffect(cameraPositionLatLongBounds) {
        cameraPositionLatLongBounds?.let {

            val latLngBounds = LatLngBounds.builder().apply {
                it.coordinates.forEach { latLong ->
                    include(LatLng(latLong.latitude, latLong.longitude))
                }
            }.build()

            cameraPositionState.move(
                CameraUpdateFactory.newLatLngBounds(latLngBounds, it.padding)
            )
        }
    }

    GoogleMap(
        cameraPositionState = cameraPositionState,
        modifier = modifier
    ) {
        markers?.forEach { marker ->
            Marker(
                state = rememberMarkerState(
                    key = marker.key,
                    position = LatLng(marker.position.latitude, marker.position.longitude)
                ),
                alpha = marker.alpha,
                title = marker.title
            )
        }

        polyLine?.let { polyLine ->
            Polyline(
                points = List(polyLine.size) {
                    val latLong = polyLine[it]
                    LatLng(latLong.latitude, latLong.longitude)
                },
                color = Color(0XFF1572D5),
                width = 16f
            )
            Polyline(
                points = List(polyLine.size) {
                    val latLong = polyLine[it]
                    LatLng(latLong.latitude, latLong.longitude)
                },
                color = Color(0XFF00AFFE),
                width = 8f
            )
        }

    }
}
@Composable
actual fun GoogleMaps(
    modifier: Modifier,
    markers: List<MapMarker>?,
    cameraPosition: CameraPosition?,
    cameraPositionLatLongBounds: CameraPositionLatLongBounds?,
    polyLine: List<LatLong>?
) {
    val mapsView = remember {
        GMSMapView()
    }

    UIKitView(
        modifier = modifier.fillMaxSize(),
        interactive = true,
        factory = {
            mapsView
        },
        update = { view ->
            cameraPosition?.let {
                view.setCamera(
                    GMSCameraPosition.cameraWithLatitude(
                        it.latLong.latitude,
                        it.latLong.longitude,
                        it.zoom
                    )
                )
            }

            cameraPositionLatLongBounds?.let {

                val bounds = GMSCoordinateBounds()
                it.coordinates.forEach {
                    bounds.includingCoordinate(
                        CLLocationCoordinate2DMake(
                            latitude = it.latitude,
                            longitude = it.longitude
                        )
                    )
                }
                GMSCameraUpdate().apply {
                    fitBounds(bounds, it.padding.toDouble())
                    view.animateWithCameraUpdate(this)
                }
            }

            markers?.forEach { marker ->
                GMSMarker().apply {
                    position = CLLocationCoordinate2DMake(
                        marker.position.latitude,
                        marker.position.longitude
                    )
                    title = marker.title
                    map = view
                }
            }

            polyLine?.let { polyLine ->
                val points = polyLine.map {
                    CLLocationCoordinate2DMake(it.latitude, it.longitude)
                }
                val path = GMSMutablePath().apply {
                    points.forEach { point ->
                        addCoordinate(point)
                    }
                }

                GMSPolyline().apply {
                    this.path = path
                    this.map = view
                }
            }
        }
    )
}

@realityexpander
Copy link
Author

realityexpander commented Sep 26, 2023

Thanks for the sample code! I can see that the code is using the native libraries on ios and android.

I'm primarily and Android native dev, so iOS is still a bit mysterious for me, especially without having example code to work from.

Is there any other special handling to use this code? Like the cocopods setup in this project? Or just a standard google setup?

Is there a more complete example of your code that I could reference for this?

Im confused about what needs to be in place on the iOS side to make this work. I can handle the Android side.

Thanks in advance!

@sdzshn3
Copy link

sdzshn3 commented Sep 26, 2023

I'm also in a stage of trail and error to make the maps work on both platforms.

As I keep adding more features, I started to have a feel like, it's better to use GoogleMaps View directly and set the view as AndroidView in Compose. This way we have a GoogleMap object which gives us full control and write better code.

And regarding integration of Maps in ios, I have used cocoapods.

in shared gradle:

kotlin {
    cocoapods {
        // ...
        pod("GoogleMaps") {
            version = "8.2.0"
        }
    }
}

After that once you do a gradle sync, you should be able to use GoogleMaps related classes in iosMain of shared module.

For API usage, refer official docs https://developers.google.com/maps/documentation/ios-sdk/config

@realityexpander
Copy link
Author

I have finally got the Android and iOS displaying maps with interactivity. There are some features on iOS that are not working properly, but the basic functionality is implemented.

Check out my solution here:

https://github.com/realityexpander/ContactsComposeMultiplatform

@andiosdev
Copy link

I'm new in KMP and Compose, can you guys give me a beginner instruction on how to integrate Google Maps in iOS?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants