iosswiftswiftui

How to handle session expire in SwiftUI


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.


Solution

  • 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.