Home > Net >  Kotlin multi platform flow block convert to custom wrapper flow use for ios
Kotlin multi platform flow block convert to custom wrapper flow use for ios

Time:06-29

I have a kotlin multi platform project which contains apollo graphql api

in this project i have BaseRepository Class and in this class there is a method to execute query or mutations

suspend fun <D : Query.Data> executeQuery(query: Query<D>): ApolloResponse<D> {
        val response = getApolloClient().query(query).execute()

        checkOperation(response)

        return response
    }

    suspend fun <D : Mutation.Data> executeMutation(mutation: Mutation<D>): ApolloResponse<D> {
        val response = getApolloClient().mutation(mutation).execute()

        checkOperation(response)

        return response
    }

For example i want to use this method in Some repository like this

class HelpRepository : BaseRepository() {

    fun test(request: AddFeedBackRequest) = flow {

        val feedBackType = if (request.type == AddFeedBackType.Bug) {
            FeedbackType.BUG
        } else {
            FeedbackType.FEEDBACK
        }

        val input = AddFeedbackInput(request.note, Optional.presentIfNotNull(feedBackType))

        emit(true)

        val mutation = AddFeedbackMutation(input)

        val response = executeMutation(mutation)

        emit(false)

    }
}

when i add the flow scope i shouldn't be had to convert this method to a suspend function

i dont want to use suspend function because of ios application. When i use suspend function its convert "Kotlinx_coroutines_coreFlowCollector" in xcode

so i found a wrapper function like this

fun <T> Flow<T>.asCommonFlow(): CommonFlow<T> = CommonFlow(this)
class CommonFlow<T>(private val origin: Flow<T>) : Flow<T> by origin {
    fun listen(block: (T) -> Unit): Closeable {
        val job = Job()

        onEach {
            block(it)
        }.launchIn(CoroutineScope(Dispatchers.Main   job))

        return object : Closeable {
            override fun close() {
                job.cancel()
            }
        }
    }
}

when i use this wrapper with single variable it works exactly what i want in xcode.

but in functions i couldn't find a proper way to do this

i need a wrapper like

= commonFlow {
}

instead of this

= flow {
}

to use this method as a commonFlow wrapper

Can you help me ?

CodePudding user response:

We have pretty much the same thing in one of our projects. We have a extension function that converts the regular flow to a "common" flow so it can be used in both Android and iOS.

You can created flow like always, and wrap it at the end.

fun <T> Flow<T>.wrap(): CommonFlow<T> = CommonFlow(this)

class HelpRepository : BaseRepository() {

fun test(request: AddFeedBackRequest) = flow {

    val feedBackType = if (request.type == AddFeedBackType.Bug) {
        FeedbackType.BUG
    } else {
        FeedbackType.FEEDBACK
    }

    val input = AddFeedbackInput(request.note, Optional.presentIfNotNull(feedBackType))

    emit(true)

    val mutation = AddFeedbackMutation(input)

    val response = executeMutation(mutation)

    emit(false)

}
}.wrap()
  • Related