I am developing a login screen in my Android application with a clean architecture.
When using the login in successfully, I need to save the token to shared preferences.
And on the splash screen, I need to check whether a user is logged in or not
So my question is that where is the perfect place:
should I save token in LoginUseCase (domain layer)
class LoginUseCase(private val userRepository: UserRepository, private val schedulerProvider: SchedulerProvider) {
fun execute(username: String, password: String): Single<Token> {
return userRepository.login(username, password)
.andThen(userRepository.saveToken(.....)
.subscribeOn(schedulerProvider.getIOScheduler())
.observeOn(schedulerProvider.getUIScheduler())
}
}
Or should I make save token as an UseCase and save the token in presenter layer
class LoginPresenter(private val view: LoginContract.View,
private val setLoginStateUseCase: SetLoginStateUseCase,
private val loginUseCase: LoginUseCase,
private val schedulerProvider: SchedulerProvider): LoginContract.Presenter {
private val compositeDisposable = CompositeDisposable()
override fun performLogin(username: String, password: String) {
if (username.isNullOrEmpty() || password.isNullOrEmpty()) {
view.onShowLoginError("Field should not be empty")
} else {
view.showLoading()
val disposable = loginUseCase.execute(username, password)
.subscribeOn(schedulerProvider.getIOScheduler())
.observeOn(schedulerProvider.getUIScheduler())
.andThen(setLoginStateUseCase.execute())
.subscribe({
view.hideLoading()
view.onLoginSuccess()
}, {error ->
view.hideLoading()
view.onShowLoginError(error.localizedMessage)
})
compositeDisposable.add(disposable)
}
}
The same question with check user is logged in or not. Should I make that action a use-case?
In my opinion it makes pretty much sense to perform that operation in the domain layer use case. Imagine you have another different module in the same project for a TV app. It's likely that the LoginPresenter
may differ from the mobile app module's one, however, you could be able to reuse the very same use case. Thus, you don't have to be aware on each LoginPresenter
variation you implement to save the token once the use case is executed.
On the other hand, I'd suggest to take a look at how the folks of Google face the login process using a delegate pattern in their Google I/O application. It's a very common pattern to use a currentUser
observable along your application giving you plenty of advantages. For example, although I wouldn't label it as a pure clean architecture reference project, the guys of kickstarter developed an interesting MVVM+RxJava
architecture using the currentUser paradigm I've talked about which deserves to have a glance also.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With