**目的:**使用SwiftUI将API数据显示到Tab栏
我尝试了什么:我尝试使用模型实现API,并将其实现为选项卡视图。但不幸的是,API结构发生了巨大的变化,一切都变得混乱。
获取API数据的代码(更新详情 * 第二次):
import SwiftUI
struct Event: Codable {
let eventId: String
let eventTitle: String
let eventStartDate: String
let eventEndDate: String
let eventImg: String
}
enum Timeline: Int {
case upcoming = 1
case past = 2
}
struct MainView: View {
@State private var events: [Event] = []
var body: some View {
TabView {
NavigationView {
if #available(iOS 14.0, *) {
List(events, id: \.eventId) { event in
VStack(alignment: .leading) {
Text(event.eventTitle)
.font(.headline)
Text(event.eventStartDate)
.font(.subheadline)
Text(event.eventEndDate)
.font(.subheadline)
if let url = URL(string: event.eventImg), let data = try? Data(contentsOf: url) {
Image(uiImage: UIImage(data: data)!)
.resizable()
.scaledToFit()
}
}
}
.navigationTitle("Upcoming Events")
} else {
// Fallback on earlier versions
}
}
.tabItem {
Image(systemName: "calendar.badge.plus")
Text("Upcoming")
}
.onAppear {
fetchEvents(timeline: .upcoming, page: 1)
}
NavigationView {
if #available(iOS 14.0, *) {
List(events, id: \.eventId) { event in
VStack(alignment: .leading) {
Text(event.eventTitle)
.font(.headline)
Text(event.eventStartDate)
.font(.subheadline)
Text(event.eventEndDate)
.font(.subheadline)
if let url = URL(string: event.eventImg), let data = try? Data(contentsOf: url) {
Image(uiImage: UIImage(data: data)!)
.resizable()
.scaledToFit()
}
}
}
.navigationTitle("Past Events")
} else {
// Fallback on earlier versions
}
}
.tabItem {
Image(systemName: "calendar.badge.minus")
Text("Past")
}
.onAppear {
fetchEvents(timeline: .upcoming, page: 1)
}
}
}
private func fetchEvents(timeline: Timeline, page: Int) {
let url = URL(string: "https://dev.myhss.org.uk/api/v1/events/eventlist")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
let body = "timeline=\(timeline.rawValue)¤t_page=\(page)"
request.httpBody = body.data(using: .utf8)
URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, let events = try? JSONDecoder().decode([String: [Event]].self, from: data) else {
print("Error fetching events: \(error?.localizedDescription ?? "Unknown error")")
return
}
DispatchQueue.main.async {
self.events = events[timeline == .upcoming ? "upcoming" : "past"] ?? []
}
}
.resume()
}
}
已实现(已有代码):这是实施的,但突然发生的剧烈变化:
如果收到的响应位于两个不同的数组中,如何使用swiftUI获取JSON API?
**问题是什么:**我已经多次尝试更改模型,但仍然无法正确获取数据。在日志中获取错误:
“获取事件时出错:未知错误”
- API url*: www.example.com
参数:(key:value)
时间轴:% 1(% 1-即将发生的事件,% 2-过去的事件)
当前页:1(1代表第1页,2代表第2页,依此类推)
body:x-www-form-unlencoded或表单数据
响应是仅为即将到来的事件获取数据的示例。当时间轴值为2时,将显示过去的事件
理想答案:
{
"status": true,
"message": "Event Listing",
"data": {
"upcoming": {
"0": {
"event_id": "5",
"event_title": "event title 5",
"event_short_description": "short desc 5",
"event_detailed_description": "details description 2",
"event_start_date": "2025-05-15 16:58:56",
"event_end_date": "0000-00-00 00:00:00",
"event_mode": "0",
"event_level": "0",
"event_level_details": null,
"event_for_karyakartas_only": "1",
"event_for_which_karyakartas": null,
"event_attendee_karyakarta_roles": null,
"event_attendee_gender": "M",
"event_age_category": null,
"event_reg_part_time_allowed": null,
"event_reg_guest_allowed": null,
"event_chargable_or_not": null,
"event_capacity": null,
"event_waiting_list_allowed": null,
"event_wait_list_capacity": null,
"event_contact": "<span>Chintu Parekh</span>\r\n<br> <span>info@myhss.org</span>\r\n<p>01255 9875585</p>",
"event_notes": "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 55 BC, making it over 2000 years old. Richard McClintock, a Latin professor",
"event_additional_info_required": null,
"event_img": "https://dev.myhss.org.uk/assets/events/event-2.png",
"event_img_detail": "https://dev.myhss.org.uk/assets/events/event-2-detail.png",
"event_created_date": "2025-05-10 16:55:08",
"event_created_by": null,
"event_online_details": null,
"offline_address_id": null,
"building_name": "",
"address_line_1": "",
"address_line_2": "",
"city": null,
"county": null,
"postal_code": "",
"country": null,
"latitude": null,
"longitude": null
},
"1": {
"event_id": "10",
"event_title": "event title 10",
"event_short_description": "short desc 10",
"event_detailed_description": "details description 2",
"event_start_date": "2025-05-15 16:58:56",
"event_end_date": "0000-00-00 00:00:00",
"event_mode": "0",
"event_level": "0",
"event_level_details": null,
"event_for_karyakartas_only": "1",
"event_for_which_karyakartas": null,
"event_attendee_karyakarta_roles": null,
"event_attendee_gender": "M",
"event_age_category": null,
"event_reg_part_time_allowed": null,
"event_reg_guest_allowed": null,
"event_chargable_or_not": null,
"event_capacity": null,
"event_waiting_list_allowed": null,
"event_wait_list_capacity": null,
"event_contact": "<span>Chintu Parekh</span>\r\n<br> <span>info@myhss.org</span>\r\n<p>01255 9875585</p>",
"event_notes": "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 55 BC, making it over 2000 years old. Richard McClintock, a Latin professor",
"event_additional_info_required": null,
"event_img": "https://dev.myhss.org.uk/assets/events/event-2.png",
"event_img_detail": "https://dev.myhss.org.uk/assets/events/event-2-detail.png",
"event_created_date": "2025-05-10 16:55:08",
"event_created_by": null,
"event_online_details": null,
"offline_address_id": null,
"building_name": "",
"address_line_1": "",
"address_line_2": "",
"city": null,
"county": null,
"postal_code": "",
"country": null,
"latitude": null,
"longitude": null
},
"2": {
"event_id": "2",
"event_title": "event title 2",
"event_short_description": "short desc 2",
"event_detailed_description": "details description 2",
"event_start_date": "2024-04-15 16:58:56",
"event_end_date": "2023-05-31 16:55:08",
"event_mode": "0",
"event_level": "0",
"event_level_details": null,
"event_for_karyakartas_only": "1",
"event_for_which_karyakartas": null,
"event_attendee_karyakarta_roles": null,
"event_attendee_gender": "M",
"event_age_category": null,
"event_reg_part_time_allowed": null,
"event_reg_guest_allowed": null,
"event_chargable_or_not": null,
"event_capacity": null,
"event_waiting_list_allowed": null,
"event_wait_list_capacity": null,
"event_contact": "<span>Chintu Parekh</span>\r\n<br> <span>info@myhss.org</span>\r\n<p>01253 9875485</p>",
"event_notes": "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor",
"event_additional_info_required": null,
"event_img": "https://dev.myhss.org.uk/assets/events/event-2.png",
"event_img_detail": "https://dev.myhss.org.uk/assets/events/event-2-detail.png",
"event_created_date": "2023-04-10 16:55:08",
"event_created_by": null,
"event_online_details": "http://netflix-events.com",
"offline_address_id": "7",
"building_name": "",
"address_line_1": "Talbot Primary School",
"address_line_2": "East Moor Road",
"city": "Leeds",
"county": "Leeds",
"postal_code": "LS8 1AF",
"country": "United Kingdom",
"latitude": "53.842083",
"longitude": "-1.51691735"
},
"3": {
"event_id": "7",
"event_title": "event title 7",
"event_short_description": "short desc 7",
"event_detailed_description": "details description 2",
"event_start_date": "2024-04-15 16:58:56",
"event_end_date": "2023-05-31 16:55:08",
"event_mode": "0",
"event_level": "0",
"event_level_details": null,
"event_for_karyakartas_only": "1",
"event_for_which_karyakartas": null,
"event_attendee_karyakarta_roles": null,
"event_attendee_gender": "M",
"event_age_category": null,
"event_reg_part_time_allowed": null,
"event_reg_guest_allowed": null,
"event_chargable_or_not": null,
"event_capacity": null,
"event_waiting_list_allowed": null,
"event_wait_list_capacity": null,
"event_contact": "<span>Chintu Parekh</span>\r\n<br> <span>info@myhss.org</span>\r\n<p>01253 9875485</p>",
"event_notes": "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor",
"event_additional_info_required": null,
"event_img": "https://dev.myhss.org.uk/assets/events/event-2.png",
"event_img_detail": "https://dev.myhss.org.uk/assets/events/event-2-detail.png",
"event_created_date": "2023-04-10 16:55:08",
"event_created_by": null,
"event_online_details": null,
"offline_address_id": null,
"building_name": "",
"address_line_1": "",
"address_line_2": "",
"city": null,
"county": null,
"postal_code": "",
"country": null,
"latitude": null,
"longitude": null
},
"4": {
"event_id": "8",
"event_title": "event title 8",
"event_short_description": "short desc 8",
"event_detailed_description": "details description 2",
"event_start_date": "2024-04-15 16:58:56",
"event_end_date": "2023-05-31 16:55:08",
"event_mode": "0",
"event_level": "0",
"event_level_details": null,
"event_for_karyakartas_only": "1",
"event_for_which_karyakartas": null,
"event_attendee_karyakarta_roles": null,
"event_attendee_gender": "M",
"event_age_category": null,
"event_reg_part_time_allowed": null,
"event_reg_guest_allowed": null,
"event_chargable_or_not": null,
"event_capacity": null,
"event_waiting_list_allowed": null,
"event_wait_list_capacity": null,
"event_contact": "<span>Chintu Parekh</span>\r\n<br> <span>info@myhss.org</span>\r\n<p>01253 9875485</p>",
"event_notes": "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor",
"event_additional_info_required": null,
"event_img": "https://dev.myhss.org.uk/assets/events/event-2.png",
"event_img_detail": "https://dev.myhss.org.uk/assets/events/event-2-detail.png",
"event_created_date": "2023-04-10 16:55:08",
"event_created_by": null,
"event_online_details": null,
"offline_address_id": null,
"building_name": "",
"address_line_1": "",
"address_line_2": "",
"city": null,
"county": null,
"postal_code": "",
"country": null,
"latitude": null,
"longitude": null
},
"total_pages": 2,
"current_page": 1,
"per_page": 5,
"pagination_links": "",
"next": 2,
"previous": 0,
"total_records": 8
},
"past": {}
}
}
1条答案
按热度按时间daupos2t1#
这里是我的工作代码
... to correctly fetch API data smoothly when the API structure is completely changed?
注意所有的细节。它使用一个动态键(AnyKey)将即将到来和过去的数据提取到一个事件数组中。剩下要做的就是单独下载图像,不使用try? Data(contentsOf: url)
,使用常规的URLSession
或AsyncImage
,如图所示。请注意,您仍然需要查阅API文档,以确定哪些属性是可选的,然后将
?
添加到这些属性中。代码中的重要部分是使用
do/try/catch
模式,在catch
中有一个print(error)
。如果没有这些,你将继续努力寻找错误的原因。