Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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

Sorry for simple question, try to learn SwiftUI

My goal is to show alert then i can not load data from internet using .alert()
the problem is that my struct for error actually has data but it does not transfer to .alert()
debug shows that AppError struct fill in with error but then i try to check for nil or not it is always nil in .Appear()

PostData.swift

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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: {})
}

}

>Solution :

Probably when doing this check, the data fetch process is not finished yet.

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

So you should wait the network request finish to check if there is error or not.

If you sure there is error and just test this try this to see error:

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

To handle better this situation you can pass a closure your fetchGuardData function and handle your result and error inside it.

or you can use .onChange for the listen the changes of appError.

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

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading