Создайте класс-оболочку, который может иметь как токен, так и результат поиска
data class TokenAndSearchResult(
val tokenResponse: TokenResponse,
val searchResponse: SearchResponse
)
Тогда хранилище:
private fun getSearchResult(): LiveData<TokenAndSearchResult> {
return LiveDataReactiveStreams.fromPublisher(remoteSource.getAuthToken()
.subscribeOn(Schedulers.io())
// .observeOn(AndroidSchedulers.mainThread()) probably won't be needed. LiveData is observed in the main thread anyway.
.flatMap { token ->
remoteSource.getSearchResult(token) // Flowable<SearchResult>
.map { result -> TokenAndSearchResult(token, result) } // Flowable<TokenAndSearchResult>
.startWith(TokenAndSearchResult(token, SearchResult()))) // Flowable<TokenAndSearchResult>
} // Flowable<TokenAndSearchResult>
)
}
В результате LiveData<TokenAndSearchResult>
выдаст один экземпляр TokenAndSearchResult
с токеном. Этот начальный экземпляр будет иметь пустой результат поиска, представленный SearchResult()
в приведенном выше примере кода.
Как только remoteSource.getSearchResult()
вернется, он сгенерирует второй раз с непустым значением SearchResult
.
ViewModel может сопоставить этот результат LiveData
с отдельным LiveData
class HomeModel {
// Declaring "var LiveData" is usually an anti-pattern, because
// LiveData shouldn't change but only the object wrapped by LiveData
// should change.
private val tokenLiveData = MediatorLiveData<TokenResponse>()
private val searchLiveData = MediatorLiveData<SearchResponse>()
fun observeTokenLiveData(): LiveData<TokenResponse> {
return tokenLiveData
}
fun observeSearchLiveData(): LiveData<SearchResponse> {
return searchLiveData
}
fun getSearchResult() {
val source = repository.getSearchResult()
tokenLiveData.addSource(source) {
tokenLiveData.value = it.tokenResponse
tokenLiveData.removeSource(source)
}
searchLiveData.addSource(source) {
searchLiveData.value = it.searchResponse
searchLiveData.removeSource(source)
}
}
}
Дополнительная мысль:
Как только приложение завершает процесс аутентификации и получает токен аутентификации, приложение обычнохочет сохранить этот токен аутентификации и не повторять этот процесс аутентификации, пока токен не истечет. Также он должен иметь логику, которая обнаруживает ошибку аутентификации 401 или 403 и повторяет попытки после обновления токена.