如何处理SwiftUI的会话过期



我正在构建遵循MVVM架构的Swift-UI应用程序。我已经实现了这样的登录流程

struct ApplicationSwitcher: View {
@EnvironmentObject var user: UserDataVM
var body: some View {
if user.isLogedIn {
HomeView()
} else {
LoginView()
}
}
}

,其中isLogedIn@Published类型的变量。流程运行良好。但是问题是,当处理会话过期时,我需要在每个API调用中处理它,并在视图中更新isLogedIn环境对象。有什么办法,我可以使这个东西可以处理在共同的地方,这样我就可以避免编写相同的代码为所有的API调用。

您可以创建一个集中的认证服务来管理用户的登录状态和会话过期,这个类可以在NetworkManger类中调用

AuthenticationService是您将调用服务以获取新令牌或检查现有令牌的有效性,然后使用isLoggedInpublished属性发布结果的地方。

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
}
}

假设NetworkManager是一个有URLSession code的类,你可以在请求之前检查用户是否为isLoggedIn,如果不是,则使用cancellable来取消任务

您可以将AuthenticationService作为依赖项传递到您拥有的网络管理器类

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
}
}
}

通过将AuthenticationService集成到您的网络层,您可以确保在每个API请求之前检查用户的登录状态。

这样可以集中处理会话过期,避免在每个API调用中重复代码。

要在ViewModel或View中接收isLoggedIn,你可以使用EnvironmentObject,因为你只需要一个属性来确定你是想在应用程序中显示home视图还是login视图。

您可以使用您的Api reason来管理会话过期。如:How You can this code

步骤1:

在ViewModel中Init一个变量Like

@Published var isSessionEnd: Bool

init(){
self.isSessionEnd = false
}

默认isSessionEnd为False。

步骤2:在你的api原因中设置值,比如当api原因消息是"你的会话是经验的";然后你可以像这样设置isSessionEnd Value为真

just for Understand

func apireasonse(){

// just Example for mesage
if apireasonsemesssage = "session ended "{
self.isSessionEnd = true
}
else{
//manage your reasonse here
}
}

步骤3:在View中,你可以设置何时isSessioEnd为真,然后显示登录屏幕在这里,你可以使用ZSTack和NavigationLink设置这两个代码都显示在

下面
struct HomeView: View {
@ObservedObject var viewModel: HomeViewViewModel

init(){
viewModel = HomeViewViewModel()
}
var body: some View {
ZStack{
//            =============
//            Conent
//            =============

if viewModel.isSessionEnd {
//                LoginView()    // here Show Login Screen
}
/// OR
NavigationLink(destination: LoginView(), isActive: $viewModel.isSessionEnd, label: { // destination: LoginView()
EmptyView()
})


}
}
}

如果你设置了会话过期的固定时间,那么在ViewModel中使用SessionExpireTime检查当前时间,如果条件与时间进行比较,如果小于Good,如果等于或大于Good,则isessionend为true set

谢谢如果你有任何问题,请随时用电报告诉我@YouKnowBKA