我想创建一个模块,它会在需要时刷新令牌并使用来自 Apple 的 Combine
重复最新请求。
目前,每个部分都运行良好,但不是这个:
public func executeRequest<T: Decodable, E: ServerErrorType>(
_ request: HTTPRequest,
mapper: ObjectMapper<T, E>
) -> AnyPublisher<(T, HTTPResponse), Error> {
return authentificator // <- handle refresh token stuff
.refreshToken(force: false)
.subscribe(on: DispatchQueue.global())
.flatMap { token in // <- on obtain token - transform it into request
---> (here)
session.publisher(for: request, mapper: mapper, token: token) // <- create request
---> (here)
.tryCatch({ error -> AnyPublisher<(T, HTTPResponse), Error> in
if let error = error as? ServerErrorType,
error.isAuthError {
return authentificator
.refreshToken(force: true)
.subscribe(on: DispatchQueue.global())
.flatMap { token -> AnyPublisher<(T, HTTPResponse), Error> in
session.publisher(for: request, mapper: mapper, token: token) //<- repeat if token refreshed
}
.eraseToAnyPublisher()
} else {
throw error
}
})
.print()
}
.receive(on: DispatchQueue.main)
.print()
.eraseToAnyPublisher()
}
在令牌过期时标记 (here)
的地方,tryCatch 不起作用,而是在控制台中打印“收到取消”。我不确定我做错了什么。有什么建议吗?
答案 0 :(得分:0)
我找到了原因 - 我的 AnyCancellable
集合变为 nil,因为 ViewModel
由于 TabBar
更新过程而导致 root SwiftUI
reinit 变为 nil。 (我有一个 TabBar
作为另一个 OptionalView
中的 View
是 root)
var body: some View {
VStack {
switch viewModel.currentFlow {
case .onboarding:
WelcomeView()
.transition(.opacity)
case .main:
MainTabBarView() // <- reinit here cause the issue
.transition(.opacity)
}
}
}
刷新令牌的代码完全正确,可能的解决方法是:
@StateObject
代替 ViewModel
@ObservedObject private var viewModel: <MyViewModel>
更新到:
@StateObject private var viewModel: <MyViewModel>
TabBar
实例。可能的修复:
private lazy let mainTabBar: MainTabBarView = .init() // <- init only once
private lazy let welcome: WelcomeView = .init()
var body: some View {
VStack {
switch viewModel.currentFlow {
case .onboarding:
welcome
.transition(.opacity)
case .main:
mainTabBar
.transition(.opacity)
}
}
}