Creating the login interactor

It is time to create our login interaction, which will serve as the model that the login presenter will interact with. Create a LoginInteractor interface in the login package containing the following code:

package com.example.messenger.ui.login

import com.example.messenger.data.local.AppPreferences
import com.example.messenger.ui.auth.AuthInteractor

interface LoginInteractor : AuthInteractor {

interface OnDetailsRetrievalFinishedListener {
fun onDetailsRetrievalSuccess()
fun onDetailsRetrievalError()
}

fun login(username: String, password: String,
listener: AuthInteractor.onAuthFinishedListener)

fun retrieveDetails(preferences: AppPreferences,
listener: OnDetailsRetrievalFinishedListener)
}

As you may have noticed, LoginInteractor extends AuthInteractorThis is similar to the way that LoginView extends AuthView. The AuthInteractor interface declares behaviors and characteristics that must be implemented by any interactor that handles authentication-related logic. Let's implement the AuthInteractor interface now.

Go ahead and add an AuthInteractor interface to the com.exampla.messenger.auth package:

package com.example.messenger.ui.auth

import com.example.messenger.data.local.AppPreferences
import com.example.messenger.data.remote.vo.UserVO

interface AuthInteractor {

var userDetails: UserVO
var accessToken: String
var submittedUsername: String
var submittedPassword: String

interface onAuthFinishedListener {
fun onAuthSuccess()
fun onAuthError()
fun onUsernameError()
fun onPasswordError()
}

fun persistAccessToken(preferences: AppPreferences)

fun persistUserDetails(preferences: AppPreferences)

}

Every interactor that is an AuthInteractor must have the following fields: userDetails, accessToken, submittedUsername, and submittedPassword. In addition, an interactor that implements AuthInteractor must have persistAccessToken(AppPreferences) and persistUserDetails(AppPreferences) methods. As the names of the methods suggest, they persist access tokens and user details to the application's SharedPreferences file. As you might have guessed, we need to create an implementation class for the LoginInteractor. We will call this class LoginInteractorImpl.

The following is the LoginInteractorImpl class with its implemented login() method. Add it to the login package within the ui package:

package com.example.messenger.ui.login

import com.example.messenger.data.local.AppPreferences
import com.example.messenger.data.remote.request.LoginRequestObject
import com.example.messenger.data.vo.UserVO
import com.example.messenger.service.MessengerApiService
import com.example.messenger.ui.auth.AuthInteractor
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers


class LoginInteractorImpl : LoginInteractor {

override lateinit var userDetails: UserVO
override lateinit var accessToken: String
override lateinit var submittedUsername: String
override lateinit var submittedPassword: String

private val service: MessengerApiService = MessengerApiService
.getInstance()

override fun login(username: String, password: String,
listener: AuthInteractor.onAuthFinishedListener) {
when {

If an empty username is submitted in the login form, the username is invalid. The listener's onUsernameError() function is called when this happens:

username.isBlank() -> listener.onUsernameError() 

Call the listener's onPasswordError() function when an empty password is submitted:

 password.isBlank() -> listener.onPasswordError()
else -> {

Initializing model's submittedUsername and submittedPassword fields and creating appropriate LoginRequestObject:

submittedUsername = username
submittedPassword = password
val requestObject = LoginRequestObject(username, password)

Using MessengerApiService to send a login request to Messenger API.

service.login(requestObject)
.subscribeOn(Schedulers.io())
// subscribing Observable to Scheduler thread
.observeOn(AndroidSchedulers.mainThread())
// setting observation to be done on the main thread
.subscribe({ res ->
if (res.code() != 403) {
accessToken = res.headers()["Authorization"] as String
listener.onAuthSuccess()
} else {

Branched reached when an HTTP 403 (forbidden) status code is returned by the server. This indicates that the login failed and the user is not
authorized to access the server.

            listener.onAuthError()
}
}, { error ->
listener.onAuthError()
error.printStackTrace()
})
}
}
}
}

login() works by first verifying that the provided username and password arguments are not blank. The onUsernameError() function of the onAuthFinishedListener is invoked when a blank username is encountered and onPasswordError() is invoked when a blank password is encountered. If neither the username nor password provided is blank, it then makes use of MessengerApiService to send a login request to the messenger API. If the login request is successful, then it sets the accessToken property to the access token retrieved from the Authorization header of the API response and then invoked the listener's onAuthSuccess() function. In a scenario when the login request fails, the onAuthError() listener function is invoked.

Having understood the login process, add the retrieveDetails(), persistAccessToken() and persistUserDetails() methods below to LoginInteractorImpl:

  override fun retrieveDetails(preferences: AppPreferences,
listener: LoginInteractor.OnDetailsRetrievalFinishedListener) {

It retrieves details of user upon initial login:

  service.echoDetails(preferences.accessToken as String)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ res ->
userDetails = res
listener.onDetailsRetrievalSuccess()},
{ error ->
listener.onDetailsRetrievalError()
error.printStackTrace()})
}

override fun persistAccessToken(preferences: AppPreferences) {
preferences.storeAccessToken(accessToken)
}

override fun persistUserDetails(preferences: AppPreferences) {
preferences.storeUserDetails(userDetails)
}

Make sure to read through the comments in the preceding code snippet carefully. They thoroughly explain the workings of the LoginInteractor. It is now time to work on the LoginPresenter.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.15.43