繁体   English   中英

从 SwiftUI 中的 ViewModel 访问 EnvironmentObject

[英]Access EnvironmentObject from ViewModel in SwiftUI

我需要在 SwiftUI 中实现一个不太复杂的用例:使用用户名和密码登录,authToken 和 refreshToken 从 API 返回,将 refreshToken 存储在 KeyChain 中,将 authToken 存储在 AppState 中(这是一个 ObservableObject (environmentObject),代码如下) . 如果我的任何请求返回 401 HTTP 响应代码(因此 accessToken 已过期),我需要刷新 accessToken 并使用新令牌重试原始请求。 但问题是我从我的 ViewModel 调用 RefreshTokenRequest,并且我无法通过 View 将令牌“返回”给 appState。 所以问题是,如何从我的 ViewModel 访问我的 environmentObject? 是否可以? 这是我在游乐场文件中简化的代码:

class AppState: ObservableObject {
    @Published var isLoggedIn: Bool = false
    @Published var token: String = ""
}

struct ProtectedView: View {
    @EnvironmentObject var appState: AppState

    var body: some View {
        VStack {
            RollerListView(token: self.appState.token)
        }
    }
}

struct Roller: Codable, Hashable {
    var scooter_name: String;
}

class RollerListVM: ObservableObject {
    @Published var rollers = [Roller]()

    func getRollers(token: String) {
        print("FETCHING ROLLERS...")
        /// Here's my API request to get the array of rollers. If the token is expired, I need to refresh it with a new request and I need to pass the new token to the appState.token variable, because I need to use the new token in all of my request instead of expired one.
        /// IF THE TOKEN IS REFRESHED, HOW CAN I PASS IT TO THE AppState.token ???
        DispatchQueue.main.async {
            self.rollers = [Roller(scooter_name: "scooter 1"), Roller(scooter_name: "scooter 2")]
        }
    }

    init(token: String) {
        self.getRollers(token: token)
    }
}

struct RollerListView: View {
    @ObservedObject private var rollerListVM: RollerListVM;
    @EnvironmentObject var appState: AppState

    var body: some View {
        List(rollerListVM.rollers, id: \.self) { roller in
            HStack {
                Text(roller.scooter_name)
            }
        }
    }

    init(token: String) {
        self.rollerListVM = RollerListVM(token: token)
    }
}

我尝试将闭包函数传递给 ViewModel 并在令牌刷新后调用它(使用新令牌作为参数),但它不起作用,因为 self 参数在闭包内发生了变化。

我该怎么做?

由于您的token有点动态,我建议您不要将它直接传递给您的视图模型。 相反,传递AppState对象并在需要时检索token

如果您检测到过期的令牌,您可以在AppState上调用一个函数,该函数获取刷新令牌并更新其token属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM