https://kotlinlang.org logo
#compose
Title
# compose
u

0xf1f1

04/01/2024, 7:32 AM
whats the best way to handle session management in a compose app ? in the activity or view model ?
p

Peter

04/01/2024, 1:38 PM
It's the same as in xml, and I think neither you suggested. It's not the best idea to manage session in Activity, because it's not always created. You could have some background WorkManager, that requires access to the current session. So even if your app is single Activity, that may not be enough. I think session manager fits in a domain layer. I usually use Hilt, to instantiate it as singleton (same lifectyle as Application class), and then inject it where I need it. For example in LoginViewModel, LogOutUseCase, etc.
u

0xf1f1

04/01/2024, 2:24 PM
Thanks. What about the actual session itself ? At the moment I have a AuthSessionViewModel which I whipped up without much thought and is passed into other view models but this feels like a code smell. I could simply pass AuthSessionViewModel.state but I am now inclining towards keeping everything in LoginViewModel and just pass its state to all VMs
p

Peter

04/01/2024, 3:07 PM
In my explanation above, I used SessionManager as an example class. That class would allow you to manage and obtain your current Session in all of your ViewModels. It's similar to having a Repository, just with a bit of logic on top. You can look at official documentation, how to implement a repository. In your case, you should at least use a repository, to persist your session. Additional stuff is always debatable. You can have SessionManager, use cases, or similar. Passing the state around, between VMs, as you described, is not ideal. You will always have some duplication, when passing session to another VM. And you will probably have some annoying events/callbacks, to talk back to the AuthSessionViewModel, if needed.
👍 1
Simple example, maybe easier to imagine, what's the idea
Copy code
@Singleton
class SessionRepository @Inject constructor() {
    private val currentSession: Session? = null  

    fun set(session: Session) {
        currentSession = session
    }

    fun get(): Session? {
        return currentSession
    }
}

class LoginViewModel @Inject constructor(
    private val repository: SessionRepository
) : ViewModel() {
    
    fun onLogin() {
        // ...
        repository.set(Session(...))
    }
}

class SettingsViewModel @Inject constructor(
    private val repository: SessionRepository
) : ViewModel() {

    val state = MutableStateFlow<SettingsState>(null)

    init {
        load()
    }

    fun load() {
        val isLoggedIn = repository.get() != null
        state.value = SettingsState(isLoggedIn)
    }

    fun onLogout() {
        // ...
        repository.set(null)
    }
}
👍 1
6 Views