I am trying to create a class that would implement fetching user's location in KMM project. I found a code that uses suspendCancellableCoroutine, but I don't really know if I am using it correctly.
LocationProvider(Android):
actual class LocationProvider(private val context: Context){
private val fusedLocationClient by lazy {
LocationServices.getFusedLocationProviderClient(context)
}
@SuppressLint("MissingPermission")
actual suspend fun getCurrentLocation(): Location? = suspendCancellableCoroutine { continuation ->
val priority = Priority.PRIORITY_BALANCED_POWER_ACCURACY
fusedLocationClient.getCurrentLocation(priority, CancellationTokenSource().token).addOnSuccessListener { location ->
location?.let {
continuation.safeResume(Location(it.latitude, it.longitude)) { continuation.cancel() }
} ?: run {
continuation.resumeWithException(Exception("Unable to get current location"))
}
}.addOnFailureListener { e ->
continuation.resumeWithException(e)
}
}
}
The thing I am concerned about here is using continuation.cancel(). It is a callback from safeResume() method that checks if continuation is active, and if its not, then the callback is invoked. So the way I think of this is that if this suspendCancellableCoroutine is no longer active, it has to be cancelled somehow. But is it good approach?
inline fun <T> Continuation<T>.safeResume(value: T, onExceptionCalled: () -> Unit) {
if (this is CancellableContinuation) {
if (isActive)
resume(value)
else
onExceptionCalled()
} else throw Exception("Must use suspendCancellableCoroutine instead of suspendCoroutine")
}