[英]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.