You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动