我正在努力寻找一个可行的答案,基本上已经设置了一个导航列表,它成功显示了模型类型的数据数组,唯一的问题是当从 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")
}
}
}
}
在开始加载数据之前设置视图。
数据加载完成后更改视图显示数据。
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
}