SwiftUI如何发起POST请求并在iOS模拟器列表展示返回数据
SwiftUI POST请求数据展示修正方案
一、网络层代码修正(含参数正确写法)
原有问题说明
- 模型字段名与返回JSON不匹配:JSON返回
err_code,原代码写了error_code - POST参数未按接口要求序列化,接口要求传JSON格式的
{"method":"My_List"} - 未对网络请求、解析做错误容错,直接用
try!和强制解包容易崩溃 - 请求成功后未给
@Published的变量赋值,视图无法监听到数据变化
修正后代码
import Foundation import Combine // 命名规范化,匹配JSON结构 struct DivisionResponse: Decodable, Hashable { var err_code : Int // 注意和返回的JSON key完全一致 var message : String var list : [DivisionItem] } struct DivisionItem: Decodable, Hashable { var ForestDivision: String } class FetchResultsViewModel : ObservableObject{ @Published var fetchedRes : [DivisionItem] = [] // 初始化空数组,避免可选值处理麻烦 func getData(){ print("开始发起请求") // 1. 按接口要求构造请求参数 let parameters = ["method": "My_List"] // 序列化为JSON data guard let postData = try? JSONSerialization.data(withJSONObject: parameters) else { print("参数序列化失败") return } // 2. 替换成你实际的接口域名+路径 比如https://你的域名/link/services.php guard let url = URL(string: "你实际的完整接口地址") else { print("URL非法") return } var request = URLRequest(url: url, timeoutInterval: 10) // 超时时间不要设无限长 request.addValue("application/json", forHTTPHeaderField: "Content-Type") request.httpMethod = "POST" request.httpBody = postData let task = URLSession.shared.dataTask(with: request) { [weak self] (data, response, error) in // 容错处理 guard let data = data, error == nil else { print("请求失败: \(error?.localizedDescription ?? "未知错误")") return } do { let resultList = try JSONDecoder().decode(DivisionResponse.self, from: data) print("请求成功: \(resultList)") DispatchQueue.main.async { // 把返回的列表赋值给监听变量,视图自动刷新 self?.fetchedRes = resultList.list } } catch { print("解析失败: \(error)") } } task.resume() } }
二、视图层代码修正
原有问题说明
- 错误嵌套
List和ForEach,List本身已经可以遍历数组 - 取值逻辑错误,没有取遍历出来的元素属性
- 没有正确调用ViewModel的
getData方法
修正后代码
import SwiftUI struct DivisionList: View { @StateObject var viewModel = FetchResultsViewModel() // iOS14+用StateObject更稳定,低版本换ObservedObject var body: some View { NavigationView { // 空状态判断 if viewModel.fetchedRes.isEmpty { Text("暂无数据") } else { List(viewModel.fetchedRes, id: \.self) { item in VStack(alignment: .leading) { Text(item.ForestDivision) } } .navigationBarTitle("林区列表") } } .onAppear { // 页面出现时发起请求 viewModel.getData() } } } struct DivisionList_Previews: PreviewProvider { static var previews: some View { DivisionList() } }
三、注意事项
- 请将网络代码中的
你实际的完整接口地址替换为你真实的请求地址,格式为域名+link/services.php,比如https://xxx.com/link/services.php - 如果需要适配iOS13以下版本,将
@StateObject替换为@ObservedObject即可 - 接口返回的
err_code可以根据业务需求添加判断,比如错误码不为成功值时展示对应提示
内容的提问来源于stack exchange,提问作者Deep Singh
相关产品推荐
相关产品推荐

