Как я могу использовать сопрограммы с моим вызовом API?Шаблон MVP - PullRequest
0 голосов
/ 11 июня 2019

Я довольно новичок в coroutines и мне интересно, что я делаю не так ... У меня есть служба, которая возвращает Object

 @GET("list/{id}")
    suspend fun getId(@Path("id") id: Long): Response<MyListResponse>

Итак, теперь у меня есть докладчик, который вызывает сценарий использования, и мой сценарий использования делает это:

class MyUseCase(val repoImpl: MyRepoImpl) {
    suspend fun execute(id: Long) = repoImpl.getListById(id)
}

И тогда мой репозиторий:

class MyRepository(val myService : MyService) {
 suspend fun getResult(id: Long) = myService.getId(id)

Я не знаю, чего мне не хватает, где мне делать сопрограмму?

Я использовал это BaseRepository

open class BaseRepository {

    suspend fun <T : Any> safeApiCall(call: suspend () -> Response<T>, errorMessage: String): T? {

        val result: Result<T> = safeApiResult(call, errorMessage)
        var data: T? = null

        when (result) {
            is Result.Success ->
                data = result.data
            is Result.Error -> {
                Log.d("1.DataRepository", "$errorMessage & Exception - ${result.exception}")
            }
        }

        return data

    }

    private suspend fun <T : Any> safeApiResult(call: suspend () -> Response<T>, errorMessage: String): Result<T> {
        val response = call.invoke()
        if (response.isSuccessful) return Result.Success(response.body()!!)

        return Result.Error(IOException("Error Occurred during getting safe Api result, Custom ERROR - $errorMessage"))
    }

}

Где Result - это класс sealed с Success и Error, но многие люди говорили мне, что Repository для вещей CRUD, поэтому он должен перейти к моему сценарию использования.

Что мне не хватает?

1 Ответ

0 голосов
/ 11 июня 2019

Если вы используете ViewModel или Presenter, я бы порекомендовал запустить здесь сопрограмму.ViewModel уже имеет свой viewModelScope (по состоянию на 2.1.0), докладчик может реализовать CoroutineScope.Это сделает его легко отменяемым, когда в этом больше нет необходимости. Что произойдет с ВМ:

fun foo(){
viewModelScope.launch(Dispatchers.Main){
  val result = myUseCase.execute(id = 1)
  // stuff happens
   }
}

Обратите внимание, что я использовал Dispatchers.Main для вызова API - поддержка функций приостановки модификации позволяет вам сделать это..

** Редактировать **

Поскольку автор использует MVP

Что вы можете сделать:

class AwesomePresenter :  CoroutineScope by CoroutineScope(Dispatchers.Main){

fun foo()
launch{
  val result = myUseCase.execute(id = 1)
  // stuff happens
   }
}

fun destroy()/* or whatever your detach/destroy method is called */{
    cancel()
}

}
...