SwiftUI 在 observedObject 更改时没有更新视图
SwiftUI didn't update the view while observedObject changed
我正在做一个登录和显示数据的应用程序。当用户登录时,数据将正确显示。当我注销并登录另一个帐户时,数据应该由调用函数以重新加载数据的 observedObject 更新。但是当我登录到应用程序时,主页视图仍然显示以前帐户的旧数据。我不知道是什么问题。我尝试了很多方法来解决,即使我在注销时清除 class 中的数据,但是,视图仍然没有更新。寻求帮助,谢谢。
struct ContentView: View {
@EnvironmentObject var authService:AuthService
var body: some View{
ZStack{
if(!authService.signedIn){
RegisterView()
}
else{
HomePageView()
}
}
}}
struct HomePageView: View {
@ObservedObject var shopList:ShopJSON = .shared
var body: some View {
TabView{
HomePromotionView(shopList: shopList)
.tabItem {
Image(systemName: "house")
}.tag(1)
NavigationView{
BookingView()
}
.tabItem {
Image(systemName: "calendar")
}.tag(3)
}
.onAppear(perform: ShopJSON.shared.reload) //I try to force reload data.
}
}
struct HomePromotionView: View {
@State private var selectedSegment = 0
@ObservedObject var shopList : ShopJSON
private let homeSegment = ["PROMOTION", "HISTORY", "MESSAGE"]
var body: some View {
NavigationView {
VStack {
ScrollView(.horizontal, showsIndicators: false){
HStack{
ForEach(shopList.shops){ item in
MerchantBar(name:item.name!, icon: item.icon!, id: item.shopID!)
}
class ShopJSON: ObservableObject {
@Published var shops = [Shops]()
@Published var bcsts = [Bcast]()
@Published var selectedID : Int?
static let shared = ShopJSON()
let auth = UserDefaults.standard.string(forKey: "Auth")
private init() {
load()
}
func reload() {
load()
}
func clear() {
self.shops = [Shops]()
self.bcsts = [Bcast]()
self.selectedID = nil
}
func load() {
let url = URL(string: "https://12345/shop/")!
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue(self.auth, forHTTPHeaderField: "token")
request.httpMethod = "GET"
URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print("No data in response: \(error?.localizedDescription ?? "Unknown error").")
return
}
if let decodedShops = try? JSONDecoder().decode(Json4Swift_Base.self, from: data) {
DispatchQueue.main.async {
self.shops = decodedShops.shops!
self.bcsts = decodedShops.bcast!
注销按钮
Text("Sign Out")
.foregroundColor(Color.gray)
.onTapGesture {
self.authService.signOut()
UserDefaults.standard.set(nil, forKey: "Auth")
//self.shopList.clear() //force clean data but view didn't update while login with another account
}
我发现了同样的问题,并通过使用 EnvironmentObjects 而不是 ObservedObjects 解决了这个问题。在数据封装方面不太理想,但它对我有用。
问题是我在 class 中声明了授权令牌。当用户注销时,class 中的令牌没有更新。它仍然会使用旧令牌来获取结果。
解决方案是在函数中获取令牌而不是在 class
中声明
解决方案:
func load() {
let url = URL(string: "https://12345/shop/")!
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let auth = UserDefaults.standard.string(forKey: "Auth")
request.setValue(auth, forHTTPHeaderField: "token")
request.httpMethod = "GET"
我正在做一个登录和显示数据的应用程序。当用户登录时,数据将正确显示。当我注销并登录另一个帐户时,数据应该由调用函数以重新加载数据的 observedObject 更新。但是当我登录到应用程序时,主页视图仍然显示以前帐户的旧数据。我不知道是什么问题。我尝试了很多方法来解决,即使我在注销时清除 class 中的数据,但是,视图仍然没有更新。寻求帮助,谢谢。
struct ContentView: View {
@EnvironmentObject var authService:AuthService
var body: some View{
ZStack{
if(!authService.signedIn){
RegisterView()
}
else{
HomePageView()
}
}
}}
struct HomePageView: View {
@ObservedObject var shopList:ShopJSON = .shared
var body: some View {
TabView{
HomePromotionView(shopList: shopList)
.tabItem {
Image(systemName: "house")
}.tag(1)
NavigationView{
BookingView()
}
.tabItem {
Image(systemName: "calendar")
}.tag(3)
}
.onAppear(perform: ShopJSON.shared.reload) //I try to force reload data.
}
}
struct HomePromotionView: View {
@State private var selectedSegment = 0
@ObservedObject var shopList : ShopJSON
private let homeSegment = ["PROMOTION", "HISTORY", "MESSAGE"]
var body: some View {
NavigationView {
VStack {
ScrollView(.horizontal, showsIndicators: false){
HStack{
ForEach(shopList.shops){ item in
MerchantBar(name:item.name!, icon: item.icon!, id: item.shopID!)
}
class ShopJSON: ObservableObject {
@Published var shops = [Shops]()
@Published var bcsts = [Bcast]()
@Published var selectedID : Int?
static let shared = ShopJSON()
let auth = UserDefaults.standard.string(forKey: "Auth")
private init() {
load()
}
func reload() {
load()
}
func clear() {
self.shops = [Shops]()
self.bcsts = [Bcast]()
self.selectedID = nil
}
func load() {
let url = URL(string: "https://12345/shop/")!
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue(self.auth, forHTTPHeaderField: "token")
request.httpMethod = "GET"
URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print("No data in response: \(error?.localizedDescription ?? "Unknown error").")
return
}
if let decodedShops = try? JSONDecoder().decode(Json4Swift_Base.self, from: data) {
DispatchQueue.main.async {
self.shops = decodedShops.shops!
self.bcsts = decodedShops.bcast!
注销按钮
Text("Sign Out")
.foregroundColor(Color.gray)
.onTapGesture {
self.authService.signOut()
UserDefaults.standard.set(nil, forKey: "Auth")
//self.shopList.clear() //force clean data but view didn't update while login with another account
}
我发现了同样的问题,并通过使用 EnvironmentObjects 而不是 ObservedObjects 解决了这个问题。在数据封装方面不太理想,但它对我有用。
问题是我在 class 中声明了授权令牌。当用户注销时,class 中的令牌没有更新。它仍然会使用旧令牌来获取结果。
解决方案是在函数中获取令牌而不是在 class
中声明解决方案:
func load() {
let url = URL(string: "https://12345/shop/")!
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let auth = UserDefaults.standard.string(forKey: "Auth")
request.setValue(auth, forHTTPHeaderField: "token")
request.httpMethod = "GET"