我正在构建遵循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
是您将调用服务以获取新令牌或检查现有令牌的有效性,然后使用isLoggedIn
published属性发布结果的地方。
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