请帮助无处可去 Swift UI 在 setupUI 之前等待从 API 加载数据

问题描述 投票:0回答:1

我正在努力寻找一个可行的答案,基本上已经设置了一个导航列表,它成功显示了模型类型的数据数组,唯一的问题是当从 API 加载数据时,内容会在数据准备好之前尝试加载以进行查看。由于

UIHostingController
未在主线程上运行,暴民解决方案出现以下错误?

func getGenres(_ completion: @escaping (CompetitionGroup?) -> ()) {

        let headers = [
            "x-rapidapi-key": "api-key***",
            "x-rapidapi-host": "football-web-pages1.p.rapidapi.com"
        ]

        let request = NSMutableURLRequest(url: NSURL(string: "https://football-web-pages1.p.rapidapi.com/competitions.json?include=rounds")! as URL,
                                                cachePolicy: .useProtocolCachePolicy,
                                            timeoutInterval: 10.0)
        request.httpMethod = "GET"
        request.allHTTPHeaderFields = headers

        let session = URLSession.shared
        let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
            if (error != nil) {
                print(error as Any)
            } else {
                let httpResponse = response as? HTTPURLResponse
                
                do {
                    let decoder = JSONDecoder()
                    let comps = try decoder.decode(CompetitionGroup.self, from: data!)
                    self.competitions = comps
                    completion(self.competitions)
                }
                catch {
                    print("Error in JSON")
                }
            }
        })

        dataTask.resume()
    }

打来电话

SetupUI()
:

private func setupUI() {
        self.view.backgroundColor = .systemBackground
        self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Logout", style: .plain, target: self, action: #selector(didTapLogout))
        
        self.view.addSubview(label)
        label.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([
            label.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            label.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
        ])
        
        
        getGenres { (array) in
            // Do operation with array
            competitionslist =  array
            let childView = UIHostingController(rootView: ContentView()) // ERROR HERE
            self.addChild(childView)
            childView.view.frame = self.view.bounds
            self.view.addSubview(childView.view)
            childView.didMove(toParent: self)
        }
        //competitionslist =  getComps()                        
        
    }

尝试过各种对 Stack Overflow 上的其他人有帮助的方法,但没有任何乐趣,这个至少可以构建。

下面是我的ContentView导航列表设置,我不明白如何在开始执行之前加载数据,竞争列表错误,因为它是零:

struct ContentView: View {
    let compse = competitionslist
    
    var body: some View {
        NavigationView {
            List {
                ForEach(compse!.competitions, id: \.id) { competition in
                                NavigationLink(destination: Text(competition.genericname ?? "")) {
                                    Image(systemName: "airplane")
                                    Text(competition.genericname ?? "")
                                }.padding()
                
                }
                .navigationTitle("Leagues")
            }
        }
    }
}
ios swift xcode asynchronous
1个回答
0
投票

在开始加载数据之前设置视图。

数据加载完成后更改视图显示数据。

private func setupUI() {
        self.view.backgroundColor = .systemBackground
        self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Logout", style: .plain, target: self, action: #selector(didTapLogout))
    
    self.view.addSubview(label)
    label.translatesAutoresizingMaskIntoConstraints = false
    
    NSLayoutConstraint.activate([
        label.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
        label.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
    ])
    
    let childView = UIHostingController(rootView: ContentView())
        self.addChild(childView)
        childView.view.frame = self.view.bounds
        self.view.addSubview(childView.view)
        childView.didMove(toParent: self)
}

private fund loadData() {
       //load data here
       // present the data in childView
}
© www.soinside.com 2019 - 2024. All rights reserved.