SwiftUI无法从嵌套数组URL获取数据并填充列表求助
问题排查与代码修正
核心问题分析
- 解码逻辑错误:目标JSON的根结构是包含
lands数组的对象,而非直接的RideTime数组,原代码直接解码[RideTime].self完全不符合JSON结构,导致数据无法解析。 - 数据类型不匹配:JSON中
is_open是布尔值(true/false),wait_time是整数(如10),但结构体中错误定义为String类型,解码时会失败。 - 数据收集缺失:即使解码正确,原代码也没有从
lands数组中提取嵌套的rides数据到展示列表。 - 缺少版权链接展示:未实现要求的"Powered by Queue-Times.com"链接。
修正后的完整代码
import SwiftUI // 根结构:匹配JSON的顶层结构 struct Wrapper: Decodable { let lands: [Land] } // 区域结构:符合Identifiable协议,字段类型匹配JSON struct Land: Decodable, Identifiable { let id: Int let name: String let rides: [RideTime] } // 游乐设施等待时间:修正数据类型,匹配JSON字段 struct RideTime: Decodable, Identifiable { let id: Int let name: String let is_open: Bool let wait_time: Int } struct ContentView: View { @State private var lands = [Land]() var body: some View { NavigationStack { // 按区域分组展示游乐设施 List(lands) { land in Section(header: Text(land.name)) { ForEach(land.rides) { ride in VStack(alignment: .leading) { Text(ride.name) .font(.headline) // 根据开放状态展示不同文本 Text(ride.is_open ? "\(ride.wait_time) mins" : "Closed") .font(.body) .foregroundColor(ride.is_open ? .primary : .red) } } } } .navigationTitle("Ride Wait Times") .task { await fetchData() } // 添加底部版权链接 .toolbar { ToolbarItem(placement: .bottomBar) { Link("Powered by Queue-Times.com", destination: URL(string: "https://queue-times.com/en-US")!) .font(.caption) } } } } func fetchData() async { guard let url = URL(string: "https://queue-times.com/parks/16/queue_times.json") else { print("无效URL") return } do { let (data, _) = try await URLSession.shared.data(from: url) // 正确解码根结构Wrapper let decodedWrapper = try JSONDecoder().decode(Wrapper.self, from: data) lands = decodedWrapper.lands } catch { print("解码失败:\(error.localizedDescription)") } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
关键改动说明
- 修正数据类型:将
RideTime中的is_open改为Bool,wait_time改为Int,完全匹配JSON返回的字段类型,避免解码失败。 - 修复解码逻辑:先解码
Wrapper类型获取完整的lands数组,再通过List+Section按区域分组展示游乐设施,贴合数据的层级结构。 - 优化展示逻辑:根据
is_open状态显示不同文本和颜色,未开放时标注红色"Closed",提升用户体验。 - 添加版权链接:在底部工具栏中加入要求的跳转链接,使用
Link组件实现功能。 - 调试友好化:将
try?改为try并捕获具体错误信息,便于排查解码问题。
内容的提问来源于stack exchange,提问作者hackanaut
相关产品推荐
相关产品推荐

