I have a KMM project that requires access to the u...
# multiplatform
c
I have a KMM project that requires access to the user's location. My locationClient is written in Kotlin in the shared module. It was all working as expected, but I'm seeing strange behavior after updating Kotlin from 1.8.2 to 1.9.2. I get the first few locations as expected, but then the delegate just stops sending locations back. I usually get 5 or 6 locations before it stops, and never more than 10. I've tested this on both the simulator and a real device, and get the same results. On the Swift side the trigger to start sending locations is in an "onAppear" block, and navigating away and back triggers another few locations to come through, but then they stop again. When the locations stop, the phone still thinks the app is listening to locations, and continues to show the appropriate privacy notification. This is correctly removed when I navigate away and stop listening to locations. LocationClient:
Copy code
actual class LocationProviderImpl : LocationProvider {
     private val locationManager = CLLocationManager()

    private class LocationDelegate : NSObject(), CLLocationManagerDelegateProtocol {
        var onLocationUpdate: ((Location?) -> Unit)? = null
        override fun locationManager(manager: CLLocationManager, didUpdateLocations: List<*>) {
//This is correctly called for the first few locations then stops
            didUpdateLocations.firstOrNull()?.let {
                val location = it as CLLocation
                location.coordinate.useContents {
                    onLocationUpdate?.invoke(Location(latitude, longitude, it.altitude))
                }
            }
        }

        override fun locationManager(manager: CLLocationManager, didFailWithError: NSError) {
//This never gets called
            onLocationUpdate?.invoke(null)
        }
    }
override fun getCurrentLocationAsFlow(): Flow<Location?> = callbackFlow {
        locationManager.requestAlwaysAuthorization()
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.distanceFilter = kCLDistanceFilterNone
        val locationDelegate = LocationDelegate()
        locationDelegate.onLocationUpdate = { location ->
            trySend(
                location
            ).isSuccess
        }
        locationManager.delegate = locationDelegate
         locationManager.startUpdatingLocation()
       awaitClose {
//This is never called
            locationManager.stopUpdatingLocation()
        }
    }.flowOn(<http://Dispatchers.IO|Dispatchers.IO>)

    fun requestBackground() {
        locationManager.allowsBackgroundLocationUpdates = true
    }

    fun stopBackground() {
        locationManager.allowsBackgroundLocationUpdates = false
    }
    fun stopLocationUpdates() {
        locationManager.stopUpdatingLocation()
    }
}
This is used as follows:
Copy code
object GpsService {

    private lateinit var locationClient: LocationProviderImpl
    private var initialized = false
    private var serviceScope = CoroutineScope(<http://Dispatchers.IO|Dispatchers.IO>)
 
 fun initialize(appModule: AppModule) {
        if (!initialized) {
            locationClient = LocationProviderImpl()
}
}
    

  fun startLocationListener() {
  locationClient.getCurrentLocationAsFlow().cancellable()
            .catch { e ->
                e.printStackTrace()
            }
            .mapNotNull { it }
            .onEach { location ->
                // send location to view
                _state.update {
                    it.copy(
                        currentLocation = location,
                        formattedAltitude = getFormattedAltitude(location.altitude)
                    )
                }
     }.launchIn(serviceScope)
    }
I get no errors or warnings (and have set breakpoints / println()s all over the place) and no error or catch blocks ever get hit, I just stop getting any locations back after the first few. It was all working fine with Kotlin 1.8.2!
e
I've also just ran into this exact same sort of behaviour you've described, I am using Kotlin 1.9.20. Were you able to find some sort of solution to this? Is there an active issue open for this that you're aware of?
249 Views