I'm building app in Swift-UI which follows MVVM architecture. I have implemented login flow like this
struct ApplicationSwitcher: View {
@EnvironmentObject var user: UserDataVM
var body: some View {
if user.isLogedIn {
HomeView()
} else {
LoginView()
}
}
}
where isLogedIn
is variable of type @Published
. The flow works fine.
But the problem is while handling session expire, I need to handle it in each API call and update isLogedIn
EnvironmentObject in View. Is there any way that I can make this thing can be handled in common place so that I can avoid writing same code for all API calls.
You can create a centralized authentication service that manages the user's login state and session expiry, this class can be called in the NetworkManger
class
The AuthenticationService
is where you would call the service to get a fresh token or maybe check the validity of the existing token and then publish results using the isLoggedIn
published property.
final class AuthenticationService: ObservableObject {
@Published var isLoggedIn: Bool = false
func checkTokenValidity() {
if
//the token is valid then set the isLoggedIn to true
isLoggedIn = true
else
isLoggedIn = false
}
func fetchNewToken() {
// once you get the token
isLoggedIn = true
}
}
Assuming that the NetworkManager
is a class where you have URLSession code
, you can check if the user isLoggedIn
before you make the request and if not then use cancellable to cancel the tasks
You can pass the AuthenticationService
as a dependency into the Network manager class that you have
final class NetworkService {
let authenticationService: AuthenticationService
init(authenticationService: AuthenticationService) {
self.authenticationService = authenticationService
}
func get() {
if authenticationService.isLoggedIn {
// Proceed with the API request
} else {
// Handle cancellation of the request
}
}
}
By integrating the AuthenticationService
into your network layer, you can ensure that the user's login state is checked before every API request.
This should centralize the handling of session expiration and avoids the need to repeat the code in every API call.
To receive the isLoggedIn in a ViewModel or a View you can use the EnvironmentObject because you just need that one property to determine if you want to display the home view or the login view in your app.