Problem with order of code execution

I write my project with SwiftUI using VIPER pattern, and i’m stuck a little bit with this problem. My problem is (as I suppose) is that Interactor function loadList calls service function, which is network task and it takes some time to finish it, and services’ function don’t have time to finish it work so Interactor function return empty array. I’m not understand how to tell my code “wait until data come and then return value”. Here is my full data path. Thanks in advance!

class PunkApiService:ObservableObject{
    
    @Published var beers = [Beer]()
    
    func loadList(at page: Int)async{
        //MARK: - Checks is URL is valid + pagination
        guard let url = URL(string: "https://api.punkapi.com/v2/beers?page=\(page)&per_page=25") else {
            print("Invalid URL")
            return
        }
        //MARK: - Creating URLSession DataTask
        let task = URLSession.shared.dataTask(with: url){ data, response, error in
            //MARK: - Handling no erros came
            guard error == nil else {
                print(error!)
                return
            }
            //MARK: - Handling data came
            guard let data = data else{
                print("Failed to load data")
                return
            }
            //MARK: - Decoding data
            do{
                let beers = try JSONDecoder().decode([Beer].self, from: data)
                //MARK: - Puting this piece of code to the main thread to update view when data is decoded
                DispatchQueue.main.async {
                    self.beers.append(contentsOf: beers)
                }
            }
            catch{
                print("Failed to decode data")
            }
        }
        task.resume()
    }
}
class BeersListInteractor:BeersListInteractorProtocol{
    private var favoriteBeers = FavoriteBeers()
    @ObservedObject private var service  = PunkApiService()
    
    //MARK: - Load list of Beers
    func loadList(at page: Int) -> [Beer] {
        service.loadList(at: page)
        return service.beers
    }
class BeersListPresenter: BeersListPresenterProtocol, ObservableObject{
    var interactor: BeersListInteractorProtocol
    
    
    init(interactor: BeersListInteractorProtocol){
        self.interactor = interactor
        
    }
    
    @Published var beers = [Beer]()
    
    func loadList(at page: Int){
        self.beers = interactor.loadList(at: page)
    }
}
struct BeersListView: View{
    @StateObject var presenter : BeersListPresenter
    
    var body: some View {
        NavigationView{
            List{
                ForEach(presenter.beers, id: \.id){ beer in
                    Text(beer.name)
                }
            }.onAppear{
                presenter.loadList(at: 1)
            }
        }
    }
}

This topic was automatically closed after 166 days. New replies are no longer allowed.