SwiftUI:调用返回数组的函数创建Text视图列表为空问题
问题解决:SwiftUI列表不显示异步加载的子域名数据
问题原因
- 异步数据加载未触发视图更新:
funky函数中,网络请求getDATA是异步执行的,函数会立刻返回初始的[""]数组给@State var SubDomains。当网络请求完成后,闭包里修改局部变量arr的操作,不会通知SwiftUI视图刷新数据。 - 数据绑定逻辑错误:视图的
SubDomains变量和funky函数里的arr没有绑定关系,异步回调中修改arr不会同步到视图的状态变量。 - CompletionHandler设计冗余:当前的回调是逐个返回子域名,既不利于批量更新数据,也不符合异步加载的最佳实践。
修复后的代码
1. 重构VTData类(优化异步回调逻辑)
class VTData { func fetchSubdomains(for domain: String, completion: @escaping ([String]) -> Void) { let token = "<TOKEN>" guard let url = URL(string: "https://www.lalalla.com/subdomains") else { fatalError("Invalid URL") } var request = URLRequest(url: url) request.httpMethod = "GET" request.setValue(token, forHTTPHeaderField: "x-apikey") let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data else { completion([]) return } do { let result = try JSONDecoder().decode(VTResponse.self, from: data) let subdomains = result.data.map { $0.id } DispatchQueue.main.async { completion(subdomains) } } catch { print("解码失败:\(error)") completion([]) } } task.resume() } }
2. 修改SwiftUI视图(正确处理异步数据加载)
import SwiftUI struct SubdomainsList: View { @State private var subdomains: [String] = [] var body: some View { VStack { List { Text("Subdomains") ForEach(subdomains, id: \.self) { subdomain in Text(subdomain) } } } .onAppear { VTData().fetchSubdomains(for: "giphy.com") { fetchedDomains in self.subdomains = fetchedDomains } } } } struct SubdomainsList_Previews: PreviewProvider { static var previews: some View { SubdomainsList() } }
3. 保留原JSON解码结构体
struct VTResponse: Decodable { let data: [VT] } struct VT: Decodable { var id: String }
关键修复点
- 将异步回调改为一次性返回整个子域名数组,避免逐个处理的冗余逻辑。
- 在
onAppear生命周期方法中触发网络请求,确保视图加载后才发起数据获取。 - 网络请求完成后切换到主队列更新
@State变量,因为SwiftUI必须在主队列更新视图状态。 - 移除原
funky函数的冗余设计,直接调用优化后的fetchSubdomains方法。
内容的提问来源于stack exchange,提问作者Saisuk
相关产品推荐
相关产品推荐

