来自 ObservableObject class 的数据不会传递给 .alert()

data from ObservableObject class do not pass to .alert()

抱歉,问题很简单,努力学习SwiftUI

我的目标是显示警报,然后我无法使用 .alert() 从 Internet 加载数据 问题是我的错误结构实际上有数据,但它不会传输到 .alert() 调试显示 AppError 结构填充错误,但随后我尝试检查是否为 nil 它在 .Appear()

中始终为 nil

PostData.swift

struct AppError: Identifiable {
    let id = UUID().uuidString
    let errorString: String
} 

NetworkManager.swift

class NetworkManager: ObservableObject {
    
    @Published var posts = [Post]()
    @Published var appError: AppError? = nil
    
    func fetchGuardData() {
        
        if let url = URL(string: "http://hn.algolia.com/api/v1/search?tags=front_page") {
            
            let session = URLSession(configuration: .default)
            
            let task = session.dataTask(with: url) { data, response, error in
                if error == nil {
                    let decorder = JSONDecoder()
                    if let safeData = data {
                        do {
                            let results = try decorder.decode(Results.self, from: safeData)
                            DispatchQueue.main.sync {
                                self.posts = results.hits }
                        } catch {
                            self.appError = AppError(errorString: error.localizedDescription)
                        }
                    } else {
                        self.appError = AppError(errorString: error!.localizedDescription)
                    }
                } else {
                    DispatchQueue.main.sync {
                        self.appError = AppError(errorString: error!.localizedDescription)
                    }
                }
            } //
            task.resume()
        } else {
            self.appError =  AppError(errorString: "No url response")
        }
    }
}

ContentView.swift

struct ContentView: View {
    @StateObject var networkManager = NetworkManager()
    @State var showAlert = false

var body: some View {
    NavigationView {
        
        List(networkManager.posts) { post in
            NavigationLink(destination: DetailView(url: post.url)) {
                HStack {
                    Text(String(post.points))
                    Text(post.title)
                }
            }
        }
        .navigationTitle("H4NEWS")
    }
    .onAppear() {
        networkManager.fetchGuardData()
        if networkManager.appError != nil {
            showAlert = true
        }
    }
    .alert(networkManager.appError?.errorString ?? "no data found", isPresented: $showAlert, actions: {})
}

}

可能在做这个检查的时候,数据获取过程还没有完成。

if networkManager.appError != nil {
    showAlert = true
}

所以你应该等待网络请求完成,检查是否有错误。

如果你确定有错误,就测试一下试试这个看看错误:

DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
    if networkManager.appError != nil {
        showAlert = true
    }
}

为了更好地处理这种情况,您可以传递一个闭包给您的 fetchGuardData 函数,并在其中处理您的结果和错误。

或者你可以使用.onChange来监听appError的变化。

.onChange(of: networkManager.appError) { newValue in }