"Receive canceled" 转换 Publisher 时
"Receive canceled" when transform Publisher
我想创建一个模块,它会在需要时刷新令牌并使用来自 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 将不起作用,而是在控制台中打印“已取消接收”。我不确定我做错了什么。有什么建议吗?
我找到了原因 - 我的 AnyCancellable
设置变为零,因为 ViewModel
由于 root TabBar
重新初始化而变为零,因为 SwiftUI
更新过程。 (我有一个 TabBar
作为另一个 View
中的 OptionalView
是根)
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)
}
}
}
我想创建一个模块,它会在需要时刷新令牌并使用来自 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 将不起作用,而是在控制台中打印“已取消接收”。我不确定我做错了什么。有什么建议吗?
我找到了原因 - 我的 AnyCancellable
设置变为零,因为 ViewModel
由于 root TabBar
重新初始化而变为零,因为 SwiftUI
更新过程。 (我有一个 TabBar
作为另一个 View
中的 OptionalView
是根)
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)
}
}
}