Доступ к EnvironmentObject из ViewModel в SwiftUI - PullRequest
0 голосов
/ 02 марта 2020

Мне нужно реализовать не слишком сложный вариант использования в SwiftUI: вход в систему с именем пользователя и паролем, authToken и refreshToken возвращаются из API, сохраняют refreshToken в KeyChain и authToken в AppState (который является ObservableObject (environmentObject), код ниже). Если какой-либо из моих запросов возвращается с кодом ответа 401 HTTP (поэтому срок действия accessToken истек), мне нужно обновить sh accessToken и повторить мой первоначальный запрос с новым токеном. Но проблема в том, что я вызываю RefreshTokenRequest из моей ViewModel, и я не могу передать токен «назад» в appState через View. Итак, вопрос в том, как я могу получить доступ к своему environmentObject из моей ViewModel? Является ли это возможным? Вот мой код, упрощенный в файле площадки:

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 и вызвать ее, если после токена refre sh (с новым токеном в качестве параметра), но это не так работает, потому что параметр self изменяется внутри замыкания.

Как мне это сделать?

1 Ответ

1 голос
/ 03 марта 2020

Поскольку ваш token несколько динамичен c, я бы посоветовал вам не передавать его непосредственно вашим моделям представлений. Скорее, передайте объект AppState и получите token при необходимости.

Если вы обнаружите токен с истекшим сроком действия, вы можете вызвать функцию на AppState, которая получает refre sh токен и обновляет его свойство token.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...