reactormonk
09/11/2023, 9:10 AMDeferred
out form a callback? got this pattern:
kotlin
val contract = ActivityResultContracts.StartActivityForResult()
suspendCoroutine { cont ->
registerForActivityResult(contract, contract.createIntent(this, client.signInIntent)) {
<createing a Deferred here>
}
}
Can I somehow pull the Deferred
directly into the suspendCoroutine
, or do I have to do all the plumbing manually?Sam
09/11/2023, 9:14 AMreactormonk
09/11/2023, 9:15 AMval client = GoogleSignIn.getClient(this, GoogleSignInOptions.DEFAULT_SIGN_IN)
val contract = ActivityResultContracts.StartActivityForResult()
suspendCoroutine { cont ->
registerForActivityResult(contract, contract.createIntent(this, client.signInIntent)) {
val account = GoogleSignIn.getSignedInAccountFromIntent(it.data)
val def = account.asDeferred()
}
}
The account
is a Task
, which I can convert to a Deferred
to avoid the plumbing from Task
to coroutines, but since I also have the registerForActivityResult
callback, I was wondering if I can reuse the plumbing.Sam
09/11/2023, 9:18 AMreactormonk
09/11/2023, 9:19 AMSam
09/11/2023, 9:22 AMasDeferred
and just connect account
directly to cont
.reactormonk
09/11/2023, 9:22 AMSam
09/11/2023, 9:23 AMsuspendCancellableCoroutine
in place of suspendCoroutine
so you can hook up all those extra callbacksreactormonk
09/11/2023, 9:24 AMsuspendCoroutine { cont ->
registerForActivityResult(contract, contract.createIntent(this, client.signInIntent)) { activityResult ->
val account = GoogleSignIn.getSignedInAccountFromIntent(activityResult.data)
account.addOnCanceledListener { cont.resumeWithException(CancellationException()) }
account.addOnCompleteListener { cont.resume(it) }
account.addOnFailureListener { cont.resumeWithException(it) }
}
}
reactormonk
09/11/2023, 9:24 AMSam
09/11/2023, 9:25 AMsuspendCancellableCoroutine
but I think that is mostly relevant if you want cancellation to flow the other way, i.e. have the Task
be cancelled when you cancel the suspended coroutineSam
09/11/2023, 9:25 AMJoffrey
09/11/2023, 9:26 AMaccount
task supports cancellation, it should be done with suspendCancellableCoroutine
.reactormonk
09/11/2023, 9:27 AMAlbert Chang
09/11/2023, 9:30 AMval contract = ActivityResultContracts.StartActivityForResult()
return coroutineScope.async {
val result = suspendCoroutine { cont ->
registerForActivityResult(contract, contract.createIntent(this, client.signInIntent)) {
cont.resume(it)
}
}
GoogleSignIn.getSignedInAccountFromIntent(result.data).await()
}
Joffrey
09/11/2023, 9:30 AMcoroutineScope.async
here?Albert Chang
09/11/2023, 9:31 AMDeffered
.reactormonk
09/11/2023, 9:31 AMJoffrey
09/11/2023, 9:31 AMreactormonk
09/11/2023, 9:31 AMJoffrey
09/11/2023, 9:33 AMregisterForActivityResult
into a suspend function. By the way, don't you need a launch
call on the ActivityResultLauncher
returned by registerForActivityResult
?reactormonk
09/11/2023, 9:35 AM