我正在我的应用程序中尝试经过身份验证的流程。
该应用程序有一个
LoginScreenView
,它将首先出现在应用程序上。
登录时,我们转到由两个视图组成的 TabView,FirstView
和 SecondView
。
SecondView
有一个注销按钮,可以让用户返回到登录屏幕。
在 FirstView
上,我们有一个始终在执行的网络调用 onAppear
.
当用户注销时,我们在
SecondView
,在第二个选项卡上;然而,onAppear
和 onDisappear
函数都在执行,即使 FirstView
没有显示。这会在我们的用例中触发 FirstView
的
onAppear
方法中的网络调用,由于我们未通过身份验证,该方法将失败。这是我的代码。
这是
FirstView
:
LoginScreen
这是
struct LoginScreenView: View {
@EnvironmentObject private var authManager: AuthManager
var body: some View {
Button("Login") {
authManager.isLoggedIn = true
}
}
}
:
FirstView
这是
struct FirstView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Hello, world!")
}
.tabItem {
Label("Hello", systemImage: "globe")
}
.onAppear {
print("First ✅")
Task {
try await loadSomeStuffFromNetwork()
}
}
.onDisappear {
print("First ❌")
}
}
}
:
SecondView
这是应用程序的根视图:
struct SecondView: View {
@EnvironmentObject private var authManager: AuthManager
var body: some View {
VStack {
Image(systemName: "flag.fill")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Goodbye, world!")
Button("Logout") {
authManager.isLoggedIn = false
}
}
.tabItem {
Label("Goodbye", systemImage: "flag")
}
.onAppear {
print("Second ✅")
}
.onDisappear {
print("Second ❌")
}
}
}
它使用在这里声明的
struct ContentView: View {
@StateObject private var authManager = AuthManager()
var body: some View {
TabView {
Group {
if isLoggedIn {
FirstView()
SecondView()
} else {
LoginScreenView()
}
}
}
.environmentObject(authManager)
}
}
:
AuthManager
正如您在代码中看到的那样,我们正在尝试根据我们是否登录来更改显示的视图,为此我们使用了
final class AuthManager: ObservableObject {
@Published var isLoggedIn: Bool = false
}
。
你觉得这段代码OK吗?你觉得这可能是苹果方面的一个错误吗?我觉得这应该不合适,但我不知道我是否遗漏了什么。我从 2022 年开始看到
这个问题,但它似乎从未得到解决(除了添加登录条件以执行网络调用的解决方法)。 另外,看到这个
other one,他们建议使用一个if-else
变量使视图只执行一次网络调用,而不是每次出现(或SwiftUI决定它出现)。
@State
用途:
struct LazyView<Content: View>: View {
let build: () -> Content
init(_ build: @autoclosure @escaping () -> Content) {
self.build = build
}
var body: Content {
build()
}
}
希望苹果尽快修复