A clean quick to use RXJava, Retrofit and View model
MIT License - Copyright (c) 2020 Abanoub Milad Nassief Hanna
abanoubcs@gmail.com
@Linkedin
@Github
Nut (Ancient Egyptian: Nwt), also known by various other transcriptions, is the goddess of the sky, stars, cosmos, mothers, astronomy, and the universe in the ancient Egyptian religion. She was seen as a star-covered woman arching over the Earth.
- implemented in MVVM
- supports RxJava
- easily handles network calls, network failure or model parsing errors
- easily fire parallel network calls
- clean structure that avoids view model leakage
- open source
- available on jitpack
- easy to integrate and extend
Add to project level build.gradle
allprojects {
repositories {
maven { url "https://jitpack.io" }
}
}
Add to app level build.gradle
dependencies {
implementation 'com.github.abanoubmilad:nut:0.4'
}
/*
*
* make your view model extends the BaseViewModel
*
*/
class BookSearchViewModel : BaseViewModel {
/*
*
* use makeNetworkRequest to consume a single provided by the retrofit interface
* network call are handled by background threads
* callbacks run on UI thread
*
*
*/
fun searchVolumes(keyword: String?, author: String?) {
makeNetworkRequest(bookRepository.searchVolumes(keyword, author), {
volumesResponseLiveData.postValue(it)
}, {
AppLogger.e("NetworkError", it.code.toString())
AppLogger.e(
"NetworkError",
it.parseAs<ErrorResponse>()?.error?.message.orEmpty()
)
})
}
/*
*
* use makeNetworkRequest providing three singles to consume each single provided by the retrofit interface
* in parallel
* network call are handled by background threads
* callbacks run on UI thread
*
*
*/
fun searchVolumesThreeParallel(
keyword: String?,
author: String?
) {
makeNetworkRequestsParallel(
bookRepository.searchVolumes(keyword, author), {
volumesResponseLiveData.postValue(it)
}, {
AppLogger.e("NetworkError", "first request" + it.code.toString())
AppLogger.e(
"NetworkError",
it.parseAs<ErrorResponse>()?.error?.message.orEmpty()
)
}, bookRepository.searchVolumes(keyword, author), {
volumesResponseLiveData.postValue(it)
}, {
AppLogger.e("NetworkError", "second request" + it.code.toString())
AppLogger.e(
"NetworkError",
it.parseAs<ErrorResponse>()?.error?.message.orEmpty()
)
},
bookRepository.searchVolumes(keyword, author), {
volumesResponseLiveData.postValue(it)
}, {
AppLogger.e("NetworkError", "third request" + it.code.toString())
AppLogger.e(
"NetworkError",
it.parseAs<ErrorResponse>()?.error?.message.orEmpty()
)
}, {
AppLogger.e("NetworkError", it.code.toString())
AppLogger.e(
"NetworkError",
it.parseAs<ErrorResponse>()?.error?.message.orEmpty()
)
})
}
/*
*
* you can use Isync inside your Application class, service or work manager
* simply implement the Isync interface
* you need to provide the CompositeDisposable
* and calling disposeIsync() when your componenet's onDestroy() is called
*
*/
@AndroidEntryPoint
class FirebaseMsgService : FirebaseMessagingService(), Isync{
@Inject
lateinit var authRepo: AuthRepo
override val disposable = CompositeDisposable()
override fun onNewToken(token: String) {
super.onNewToken(token)
makeNetworkRequest(authRepo.updateNotificationToken(token), {
}, {
})
}
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
}
override fun onDestroy() {
super.onDestroy()
disposeIsync()
}
}
}