如何解决转换发布者时“接收已取消”
我想创建一个模块,它会在需要时刷新令牌并使用来自 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,Error> in
if let error = error as? ServerErrorType,error.isAuthError {
return authentificator
.refreshToken(force: true)
.subscribe(on: DispatchQueue.global())
.flatMap { token -> AnyPublisher<(T,Error> in
session.publisher(for: request,token: token) //<- repeat if token refreshed
}
.eraseToAnyPublisher()
} else {
throw error
}
})
.print()
}
.receive(on: DispatchQueue.main)
.print()
.eraseToAnyPublisher()
}
在令牌过期时标记 (here)
的地方,tryCatch 不起作用,而是在控制台中打印“收到取消”。我不确定我做错了什么。有什么建议吗?
解决方法
我找到了原因 - 我的 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)
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。