我试图在URLSession中更新environmentObject。
我的登录视图。
struct LoginView: View {
@EnvironmentObject var env: Env
...
var body: some View {
Group {
if env.isLogin { // 2 but the env.isLogin is still false
UserView()
} else {
VStack {
...
Button(action: {
self.login(name: self.name, pass: self.pass)
}) {
Text("Login")
}
Text("isLogin: \(String(env.isLogin))")
}
.padding()
}
}
}
func login(name: String, pass: String) {
...
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
if let decodedResponse = try? JSONDecoder().decode(Response.self, from: data) {
DispatchQueue.main.async {
...
if ... {
self.env.isLogin = true
print(self.system.isLogin) // 1 output true
}
}
return
}
}
print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")")
}.resume()
}
}
我的开始视图。
class Env: ObservableObject {
@Published var isLogin: Bool = false
}
struct ContentView: View {
let env = Env()
var body: some View {
VStack {
if env.isLogin {
UserView()
} else {
LoginView()
}
}
.environmentObject(env)
}
}
我可以确保在位置1
处将isLogin更新为true,但是env的相关属性在位置2
处不会对其进行响应。
分辨率
我创建另一个视图LoginToOtherView
,并将其替换为ContentView。
struct LoginToOtherView: View {
@EnvironmentObject var env: Env
var body: some View {
Group {
if env.isLogin {
UserView()
}
}
}
}
// and in place 2.
if env.isLogin {
LoginToOtherView()
}
答案 0 :(得分:1)
我简化了向可测试模块提供的代码快照后,一切工作正常。经过Xcode 11.4beta2测试。
完整的可测试模块:
class Env: ObservableObject {
@Published var isLogin: Bool = false
}
struct LoginViewEnv: View {
@EnvironmentObject var env: Env
var body: some View {
Group {
if env.isLogin {
Text("UserView") // << shown in 2 secs after button click
} else {
VStack {
Button(action: {
self.login(name: "name", pass: "pass")
}) {
Text("Login")
}
Text("isLogin: \(String(env.isLogin))")
}
.padding()
}
}
}
func login(name: String, pass: String) {
// simulate async login
DispatchQueue.global(qos: .background).asyncAfter(deadline: .now( ) + 2) {
DispatchQueue.main.async {
self.env.isLogin = true
print(self.env.isLogin)
}
}
}
}
struct TestVStackEnv: View {
let env = Env()
var body: some View {
VStack {
if env.isLogin {
Text("UserView")
} else {
LoginViewEnv()
}
}
.environmentObject(env)
}
}
struct TestVStackEnv_Previews: PreviewProvider {
static var previews: some View {
TestVStackEnv()
}
}