Swift3 iOS中如何通过实体类构建JSON并发送POST请求?
在Swift 3中将自定义模型转换为指定格式JSON的解决方案
你已经搭好了模型结构,现在只需要给模型添加转字典的逻辑,再结合你熟悉的登录请求代码,就能轻松生成目标格式的JSON并发送请求了,下面一步步来:
第一步:给每个模型添加转字典方法
JSONSerialization只能直接处理字典、数组这类基础类型,所以我们需要把自定义模型的属性转换成[String: Any]格式的字典(数组则转成[[String: Any]])。修改你的模型类:
import Foundation class RequestModel { var CompanyId: Int? = 0 var RollupYear: Int? = 0 var UserId: Int? = 0 var dataRollupArr = NSMutableArray() var seasonalityArr = NSMutableArray() // 核心:将模型转为符合要求的字典 func toDictionary() -> [String: Any] { // 把dataRollupArr里的模型逐个转成字典 let dataRollupDictList = dataRollupArr.compactMap { ($0 as? DataRollupModel)?.toDictionary() } // 处理seasonalityArr同理 let seasonalityDictList = seasonalityArr.compactMap { ($0 as? SeasonalityModel)?.toDictionary() } return [ "CompanyId": CompanyId ?? 0, "RollupYear": RollupYear ?? 0, "UserId": UserId ?? 0, "datarollup": dataRollupDictList, // 注意这里key是小写开头的datarollup,和目标JSON完全匹配 "Seasonalitylist": seasonalityDictList // 这个key也要和目标JSON一致 ] } } class DataRollupModel { var Name: String? = "" var CurrentValue: Float? = 0.0 var RollupYear: Int? = 0 var DataRollupColumnID: Int? = 0 func toDictionary() -> [String: Any] { return [ "Name": Name ?? "", "RollupYear": RollupYear ?? 0, "DataRollupColumnID": DataRollupColumnID ?? 0, "CurrentValue": CurrentValue ?? 0.0 ] } } class SeasonalityModel { var CompanyPeriodId: Int? = 0 var UserId: Int? = 0 var Seasonality: Int? = 0 func toDictionary() -> [String: Any] { return [ "CompanyPeriodId": CompanyPeriodId ?? 0, "UserId": UserId ?? 0, "Seasonality": Seasonality ?? 0 ] } }
第二步:封装请求方法(参考你的登录代码)
假设你已经填充好RequestModel的实例数据,比如:
// 示例:创建并填充模型数据 let rollupRequest = RequestModel() rollupRequest.CompanyId = 162 rollupRequest.RollupYear = 2018 rollupRequest.UserId = 1609 // 添加datarollup数据 let cardItem = DataRollupModel() cardItem.Name = "Thank You Cards" cardItem.RollupYear = 2018 cardItem.DataRollupColumnID = 210 cardItem.CurrentValue = 520.0 rollupRequest.dataRollupArr.add(cardItem) let callItem = DataRollupModel() callItem.Name = "Prospecting Calls" callItem.RollupYear = 2018 callItem.DataRollupColumnID = 212 callItem.CurrentValue = 1300.0 rollupRequest.dataRollupArr.add(callItem) // 添加Seasonalitylist数据 let season1 = SeasonalityModel() season1.CompanyPeriodId = 386 season1.UserId = 1609 season1.Seasonality = 25 rollupRequest.seasonalityArr.add(season1) let season2 = SeasonalityModel() season2.CompanyPeriodId = 387 season2.UserId = 1609 season2.Seasonality = 25 rollupRequest.seasonalityArr.add(season2)
然后写和登录逻辑类似的请求方法:
func sendRollupData(model: RequestModel, completion:@escaping (NSDictionary) -> ()) { // 替换成你的实际接口地址 guard let url = URL(string: baseurl + "your-rollup-api-endpoint") else { let errorDict = ["error_status": true, "message": "无效的接口地址"] as [String: Any] completion(errorDict as NSDictionary) return } var request = URLRequest(url: url) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.setValue("732rguiqfw9237ryu4k2141", forHTTPHeaderField: "KEY") do { // 把模型转成字典,再序列化JSON数据 let requestDict = model.toDictionary() let jsonData = try JSONSerialization.data(withJSONObject: requestDict, options: []) request.httpBody = jsonData let task = URLSession.shared.dataTask(with: request) { data, response, error in do { if let data = data, let responseDict = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? NSDictionary, error == nil { completion(responseDict) } else { let errorMsg = error?.localizedDescription ?? "未知错误" print("请求失败:\(errorMsg)") let errorDict = ["error_status": true, "message": errorMsg] as [String: Any] completion(errorDict as NSDictionary) } } catch { let errorMsg = error.localizedDescription print("解析返回数据失败:\(errorMsg)") let errorDict = ["error_status": true, "message": errorMsg] as [String: Any] completion(errorDict as NSDictionary) } } task.resume() } catch { let errorMsg = error.localizedDescription print("模型转JSON失败:\(errorMsg)") let errorDict = ["error_status": true, "message": errorMsg] as [String: Any] completion(errorDict as NSDictionary) } }
最后调用请求方法
sendRollupData(model: rollupRequest) { response in // 处理服务器返回的结果 print(response) }
关键注意点
- 字典的key必须和目标JSON完全一致(比如
datarollup是小写开头,别写错),否则服务器可能无法正确解析。 - 用
compactMap过滤数组中可能的nil值,避免序列化JSON时出错。 - 可选属性用
??设置默认值,防止因为属性为nil导致序列化失败。
内容的提问来源于stack exchange,提问作者user2786




