You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 04:24:04