Hey! I am trying to use clustering in my GoogleMap...
# compose-ios
e
Hey! I am trying to use clustering in my GoogleMaps screen and for that I need to install
Google-Maps-iOS-Utils
. I am using CocoaPods to be able to use the code in my Kotlin files. For GoogleMaps it works fine, but when I try to add the
Google-Maps-iOS-Utils
pod, I am getting errors. (I continue in thread)
馃У 1
1) The first problem is the version, the latest version (
v6.0.0
) requires
GoogleMaps 9.0
, and for some reason, my project can only install the version
8.0.0
, if I try to install the GoogleMaps pod with higher version (
8.3.0
,
8.3.1
,
8.4.0
,
9.0.0
,
9.1.0
and
9.1.1
) I get this error when I try to build in XCode:
Copy code
Showing All Errors Only
Failed to load XCFramework at '/Users/user/myproject/iosApp/Pods/GoogleMaps/Base/Frameworks/GoogleMapsBase.xcframework': 'HeadersPath' is not supported for a 'framework' in library 'ios-arm64'.
2) As I have to stay in the version
8.0.0
, the latest version compatible of
Google-Maps-iOS-Utils
is
v5.0.0
. So I add in my `Podfile`:
Copy code
# Uncomment the next line to define a global platform for your project
platform :ios, '16.0'

target 'iosApp' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks! :linkage => :static

  # Pods for iosApp
  pod 'shared', :path => '../shared'
  pod 'GoogleMaps', '8.0.0'
  pod 'Google-Maps-iOS-Utils', '5.0.0'
end
And in my
build.gradle
Copy code
cocoapods {
        summary = "Some description for the Shared Module"
        homepage = "Link to the Shared Module homepage"
        version = "1.0"
        ios.deploymentTarget = "16.0"
        podfile = project.file("../iosApp/Podfile")
        framework {
            baseName = "shared"
            isStatic = true
        }
        pod("GoogleMaps") {
            extraOpts += listOf("-compiler-option", "-fmodules")
        }
        pod("Google-Maps-iOS-Utils") {
            extraOpts += listOf("-compiler-option", "-fmodules")
        }
    }
I get the following errors when syncing the project (attached images). And when running in Xcode, everything looks to work fine until it gets the step:
Copy code
> Task :shared:cinteropGoogle_Maps_iOS_UtilsIosSimulatorArm64 FAILED


Showing All Issues
Exception in thread "main" java.lang.Error: /var/folders/qn/1f2__ymn7rx9382fc4hcxqth0000gn/T/7410914245776930564.m:1:9: fatal error: module 'Google_Maps_iOS_Utils' not found

	at org.jetbrains.kotlin.native.interop.indexer.UtilsKt.ensureNoCompileErrors(Utils.kt:328)

	at org.jetbrains.kotlin.native.interop.indexer.ModuleSupportKt.getModulesASTFiles(ModuleSupport.kt:83)

	at org.jetbrains.kotlin.native.interop.indexer.ModuleSupportKt.getModulesInfo(ModuleSupport.kt:15)

	at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.buildNativeLibrary(main.kt:578)

	at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.processCLib(main.kt:322)

	at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.processCLibSafe(main.kt:244)

	at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.access$processCLibSafe(main.kt:1)

	at org.jetbrains.kotlin.native.interop.gen.jvm.Interop.interop(main.kt:102)

	at org.jetbrains.kotlin.cli.utilities.InteropCompilerKt.invokeInterop(InteropCompiler.kt:49)

	at org.jetbrains.kotlin.cli.utilities.MainKt.mainImpl(main.kt:23)

	at org.jetbrains.kotlin.cli.utilities.MainKt.main(main.kt:44)
Did somebody of you guys faced this issue or understands what is going on? Just as information I am using Macbook Pro M3 (i mention it beause of the
arm-64
thing. Kotlin 2.0.21-RC Thanks in advance!
m
This is my podfile --
Copy code
pod("GoogleMaps") {
    version = "9.0.0"
    extraOpts += listOf("-compiler-option", "-fmodules")
}
pod("Google-Maps-iOS-Utils") {
    moduleName = "GoogleMapsUtils"
    version = "6.0.0"
    extraOpts += listOf("-compiler-option", "-fmodules")
}
I import these into the core iOS App --
Copy code
import GoogleMaps
import GoogleMapsUtils
If using in a KT compose view --
Copy code
import cocoapods.GoogleMaps.GMSMarker
import cocoapods.GoogleMaps.GMSCameraPosition
import cocoapods.GoogleMaps.GMSMapViewDelegateProtocol
import cocoapods.Google_Maps_iOS_Utils.GMUClusterManager
import cocoapods.Google_Maps_iOS_Utils.GMUDefaultClusterIconGenerator
You can see the imports are a bit wonky there, but I've got it running. Now, full working? I've got some issues I'm trying to work through but i'm able to build and put both markers and clusters on the map atm
They just don't stay there very long -.-
I think you specifically have an issue with another area of the import though and probably could use this blog to help out -- https://blog.protein.tech/how-to-implement-google-maps-or-any-library-with-cocoapods-in-kmp-abc73cec40ee
e
I already fixed it with a comment in other thread, thank you anyway for the response, I should put the solution here as well 馃榿馃檹
Now struggling with the marker click, but I'm on it
m
Oh, gotcha. Are you doing clustering? My markers and clusters disappear after a while -- but i've got marker clicks popping up the snippets
e
They don't disappear, no, they are there and all fine. I see snippet too, but in my case I need a custom logic for the on click
m
ahh, fair, yeah, that's the next stage for me, i've gotta get them to stop disappearing though. Are you running the code inside of a composable or is it native swift on the map front?
e
I am doing in the kotlin native side. I was having issues not rendering markers that I fixed adding
remember
to the
GMSMapView()
and
GMUClusterManager(mapView, clusterAlgorithm, clusterRenderer)
, which are initialized outside of the
UIKitView
and adding the markers in the
update
block
m
okay, cool. I didn't realize the manager would need a remember as well. And moving the marker add function to the update block is something I haven't tried -- Thanks, I'll give those a shot and should be working on click stuff tonight again. If I get the delegate stuff going for that, I'll let you know. I've got android working fine and am getting an app up to parity in iOS. We've got a bunch of functions passed between things for drawers and side menus and whatnot that interact from clicks to the map, so i've got a ways to go on the ios front
馃檶 1
e
Copy code
@Composable
actual fun GoogleMapView(
    items: ImmutableList<Location>
) {
    val mapView = remember { GMSMapView() }

    val clusterIconGenerator = GMUDefaultClusterIconGenerator()
    val clusterAlgorithm = GMUNonHierarchicalDistanceBasedAlgorithm()
    val clusterRenderer = GMUDefaultClusterRenderer(mapView, clusterIconGenerator)

    val clusterManager =
        remember {
            GMUClusterManager(mapView, clusterAlgorithm, clusterRenderer)
        }
    UIKitView(
        factory = {
            ...
            mapView
        },
        update = {
            mapView.clear()
            clusterManager.clearItems()

            if (items.isNotEmpty()) {
                items.forEach { item ->
                    clusterManager.addItem(ClusterItem(item))
                }
                clusterManager.cluster()
            }
        },
        properties =
            UIKitInteropProperties(
                interactionMode = UIKitInteropInteractionMode.NonCooperative,
            ),
        modifier = modifier.fillMaxSize(),
        onRelease = {
            it.removeFromSuperview()
        },
    )
}
馃檹 1
m
Awesome, yeah, didn't think about checking those out. Just gotta play with the interactions this evening.
I'm assuming you got it worked out, but here's my delegate if you need @Enol Sim贸n:
Copy code
val delegate = remember {
        object : NSObject(), GMSMapViewDelegateProtocol {
            override fun mapView(
                mapView: GMSMapView,
                didTapMarker: cocoapods.Google_Maps_iOS_Utils.GMSMarker,
            ): Boolean {
                val userData = didTapMarker.userData()
                if (userData is ShindigEvent) {
                    onMarkerClick(googleMapViewEntries[0])
                }
                return false
            }

            // Note: this shows an error,
            // but it compiles and runs fine(!)
            // Kotlin doesn't like the multi overload, but it is swift compliant
            override fun mapView(
                mapView: GMSMapView,
                didTapInfoWindowOfMarker: cocoapods.Google_Maps_iOS_Utils.GMSMarker,
            ) {
                val shindigEvent = (didTapInfoWindowOfMarker.userData() as ShindigEvent)
                onMarkerInfoClick(shindigEvent)
            }

            // Note: this shows an error,
            // but it compiles and runs fine(!)
            // Kotlin doesn't like the multi overload, but it is swift compliant
            override fun mapView(
                mapView: GMSMapView,
                didCloseInfoWindowOfMarker: cocoapods.Google_Maps_iOS_Utils.GMSMarker,
            ) {
                val shindigEvent = (didCloseInfoWindowOfMarker.userData() as ShindigEvent)
                onMarkerInfoClose(shindigEvent)
            }
        }
    }
e
Yes I did 馃ザ exactly the same way, I was just overthinking because of the error that shows the compiler, but I run it and it works ok, now next step, customize markers 馃榿馃挭
m
lol, yeah, i've got colors customized, but that's it for right now -- i've got another project to step to for a bit and then will come back to that -- my bigger one is wanting to customize the actual clusters (like I do in google maps compose for android) but that may be out of the question for this project 馃槢 and yeah, I spent a good while on the errors and then realized it builds fine. Also, the way I was adding/removing markers was causing some conflicts and crashes on the update, so I only add and initialize once per map load atm to enable the delegates to go all the way through and stuff, but the data comes from another viewModel anyways, so basically should only be reloaded when filtering and things apply (until we need more complexity) Definitely a slog through, but glad we're all getting things going!
馃檶 1