簡體   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