Skip to content

Commit 2877ca0

Browse files
authored
feature: Coroutine Task Wrapper (#1064)
* feature: Coroutine Task Wrapper - Add extension functions to wrap Task in coroutine - Update libs * feature: Coroutine Task Wrapper - Suppress unused - Correct logic for background threading
1 parent 797786f commit 2877ca0

File tree

4 files changed

+64
-2
lines changed

4 files changed

+64
-2
lines changed

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
buildscript {
2-
ext.kotlin_version = "1.3.72"
2+
ext.kotlin_version = "1.4.10"
33
repositories {
44
google()
55
jcenter()

coroutines/README.md

+27
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,33 @@ launch { // Coroutine builder
7272

7373
We can save, pinning and fetch parse objects use coroutines as well.
7474

75+
## Task Wrapper
76+
Coroutine support can be provided as an extension method on any `Task`. For example:
77+
```kotlin
78+
suspend fun anonymousLogin() {
79+
try {
80+
val user = ParseAnonymousUtils.logInInBackground().suspendGet()
81+
Timber.d("Logged in with user ${user.objectId}")
82+
} catch (e: ParseException) {
83+
Timber.e(e)
84+
}
85+
}
86+
```
87+
Tasks with a Void results, ie. `Task<Void>` can be made into a `Completable`.
88+
For example:
89+
```kotlin
90+
suspend fun updateUserLastLogIn() {
91+
val user = ParseUser.getCurrentUser()
92+
user.put("lastLoggedIn", System.currentTimeMillis())
93+
try {
94+
user.saveInBackground().suspendRun()
95+
Timber.d("user saved")
96+
} catch (e: ParseException) {
97+
Timber.e(it)
98+
}
99+
}
100+
```
101+
75102
## Contributing
76103
When contributing to the `coroutines` module, please first consider if the extension function you are wanting to add would potentially be better suited in the main `parse` module. If it is something specific to Kotlin users or only useful in a Kotlin project, feel free to make a PR adding it to this module. Otherwise, consider adding the addition to the `parse` module itself, so that it is still usable in Java.
77104

coroutines/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ android {
2929
}
3030

3131
ext {
32-
coroutinesVersion = "1.3.3"
32+
coroutinesVersion = "1.3.9"
3333
}
3434

3535
dependencies {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
@file:JvmName("ParseTaskExtensions")
2+
@file:Suppress("unused")
3+
4+
package com.parse.coroutines
5+
6+
import com.parse.boltsinternal.Task
7+
import kotlinx.coroutines.CoroutineDispatcher
8+
import kotlinx.coroutines.Dispatchers
9+
import kotlinx.coroutines.withContext
10+
import kotlin.coroutines.resume
11+
import kotlin.coroutines.resumeWithException
12+
import kotlin.coroutines.suspendCoroutine
13+
14+
@Suppress("BlockingMethodInNonBlockingContext")
15+
suspend fun <T> Task<T>.suspendGet(dispatcher: CoroutineDispatcher = Dispatchers.IO) = withContext<T>(dispatcher) {
16+
return@withContext suspendCoroutine { continuation ->
17+
waitForCompletion()
18+
if (isFaulted) {
19+
continuation.resumeWithException(error)
20+
}
21+
continuation.resume(result)
22+
}
23+
}
24+
25+
@Suppress("BlockingMethodInNonBlockingContext")
26+
suspend fun Task<Void>.suspendRun(dispatcher: CoroutineDispatcher = Dispatchers.IO) = withContext<Unit>(dispatcher) {
27+
return@withContext suspendCoroutine { continuation ->
28+
waitForCompletion()
29+
if (isFaulted) {
30+
continuation.resumeWithException(error)
31+
}
32+
continuation.resume(Unit)
33+
}
34+
}
35+

0 commit comments

Comments
 (0)