Ручка RetroFit geneir c ответов в Kotlin - PullRequest
0 голосов
/ 19 февраля 2020

У меня в настоящее время есть конечные точки login и register, которые возвращают аналогичные JSON, первая возвращает токен JWT, а вторая - идентификатор пользователя, в любом случае в моем хранилище у меня есть код:

suspend fun login(user: User) = try {
    val response = api.login(user)
    LoginResult.Content(response.token)
} catch (t: Throwable) {
    LoginResult.Error(t)
}

suspend fun register(user: User) = try {
    val response = api.register(user)
    RegisterResult.Content(response.id!!)
} catch (t: Throwable) {
    RegisterResult.Error(t)
}

Мой LoginResult выглядит следующим образом:

sealed class LoginResult {
    data class Content(val accessToken: String) : LoginResult()
    data class Error(val throwable: Throwable) : LoginResult()
}

и мой RegisterResult выглядит очень похоже:

sealed class RegisterResult {
    data class Content(val id: Int) : RegisterResult()
    data class Error(val throwable: Throwable) : RegisterResult()
}

Очевидно, у меня много дублирующегося кода между этими двумя и учитывая, что у меня будет еще много запросов на обработку, будет только хуже. Помимо этого, есть также соответствующие ViewStates, о которых стоит подумать.

sealed class LoginViewState {
    object Loading : LoginViewState()
    data class Content(val accessToken: String) : LoginViewState()
    data class Error(val throwable: Throwable) : LoginViewState()
}

Аналогичный существует для регистра, и они используются в Motors:

class LoginMotor : ViewModel() {
    private val _results = MutableLiveData<LoginViewState>()
    val results: LiveData<LoginViewState> = _results

    fun login(user: User) {
        _results.value = LoginViewState.Loading

        viewModelScope.launch(Dispatchers.Main) {
            val result = AuthRepository.login(user)

            _results.value = when (result) {
                is LoginResult.Content -> { LoginViewState.Content(result.accessToken) }
                is LoginResult.Error -> LoginViewState.Error(result.throwable)
            }
        }
    }
}

и другом таком двигателе для Регистрация. Сейчас я пытаюсь использовать обобщенный c подход и могу добавить обобщенные значения к EndpointResult, но как мне сделать ViewState generi c, когда мне нужно использовать состояние Loading, которое объект и не может быть обобщенным c, так как это синглтон? Это не работает:

sealed class DataViewState<T> {
    object Loading : LoginViewState() //error
    data class Content<T>(val data: T) : LoginViewState<T>()
    data class Error(val throwable: Throwable) : LoginViewState()
}

1 Ответ

0 голосов
/ 19 февраля 2020

Я придумал решение:

sealed class DataViewState {
    object Loading: DataViewState()
    data class Content<T>(val data: T): DataViewState()
    data class Error(val throwable: Throwable): DataViewState()
}
sealed class GenericResult {
    data class Content<T>(val data: T) : GenericResult()
    data class Error(val throwable: Throwable) : GenericResult()
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...