My MainRepository
- это то, что выбирает данные из API и вставляет их в базу данных, а затем отображает в пользовательском интерфейсе.
override fun fetchAll() {
Observable.fromCallable { local.fetchPosts() }
.doOnNext {
remote.fetchPosts().concatMap { posts ->
local.insert(*posts.toTypedArray())
Observable.just(posts)
}
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ outcome.success(it) },
{ error: Throwable -> outcome.failed(error) }
).addTo(compositeDisposable)
}
Переменная outcome
представляет собой PublishObject
типа Response
, то есть Loading
, Success
или Failure
.
override val outcome = PublishSubject.create<Response<List<Post>>>()
[...]
sealed class Response<T> {
companion object {
fun <T> loading(loading: Boolean): Response<T> = Progress(loading)
fun <T> success(data: T): Response<T> = Success(data)
fun <T> failure(e: Throwable): Response<T> = Failure(e)
}
data class Progress<T>(var loading: Boolean) : Response<T>()
data class Success<T>(var data: T) : Response<T>()
data class Failure<T>(var e: Throwable) : Response<T>()
}
Он выполняет метод local.fetchPosts()
, который является функцией, отвечающей за доступ к функциям DAO.
fun fetchPosts() = database.postDao().fetchAll()
[...]
@Query("SELECT * FROM posts ORDER BY createdAt DESC")
fun fetchAll(): List<Post>
addTo
является расширением Disposable
:
fun Disposable.addTo(compositeDisposable: CompositeDisposable) {
compositeDisposable.add(this)
}
Я пытался использовать concatMap
сразу после Observable.fromCallable
, но он будет отображать данные из API напрямую, а doOnNext
будет отображаться из базы данных, но не будет обновлять список, удаляя то, что было удалено из удаленный сервер.