Swift中使用Alamofire发送数组格式API参数的问题
问题:生成符合要求的JSON对象数组作为API参数
需要发送JSON对象数组作为API参数,目标格式如下:
[ { "value": "string", "recorded_at": "2024-02-27T06:13:28.102Z", "type": "string", "unit": "string", "note": "string", "recorder_method": "device", "meta_data": { "additionalProp1": "string", "additionalProp2": "string", "additionalProp3": "string" } }, { "value": "string", "recorded_at": "2024-02-27T06:13:28.102Z", "type": "string", "unit": "string", "note": "string", "recorder_method": "device", "meta_data": { "additionalProp1": "string", "additionalProp2": "string", "additionalProp3": "string" } } ]
现有代码生成的数组格式不符合要求,代码如下:
let params = [ "value": dataValue , "recorded_at" : "\(value)", "type" : paramValueType, "unit" : unitValue, "note" : addNote ?? "", "recorder_method" : "device" ] as [String : Any] arrayOfObjects = [params] var request = URLRequest(url: url! ) request.httpMethod = "POST" request.setValue(strToken, forHTTPHeaderField: "Header") request.httpBody = try! JSONSerialization.data(withJSONObject: arrayOfObjects) AF.request(request) .responseJSON { response in switch response.result { case .failure(let error): print(error) case .success(let responseObject): print(responseObject) } }
解决方案
核心问题分析
现有代码的问题在于:
- 缺少目标格式要求的
meta_data字段 - 数组仅包含单个对象,无法满足多对象提交需求
- 未设置
Content-Type: application/json请求头,可能导致API解析异常
修正方案1:手动构建符合要求的字典数组
// 构建meta_data字典 let metaData = [ "additionalProp1": "your_custom_value1", "additionalProp2": "your_custom_value2", "additionalProp3": "your_custom_value3" ] // 构建第一个数据对象 let param1 = [ "value": dataValue, // 确保recorded_at是ISO8601格式字符串,推荐用DateFormatter生成 "recorded_at": ISO8601DateFormatter().string(from: Date()), "type": paramValueType, "unit": unitValue, "note": addNote ?? "", "recorder_method": "device", "meta_data": metaData ] as [String: Any] // 构建第二个数据对象(按需添加更多) let param2 = [ "value": another_data_value, "recorded_at": ISO8601DateFormatter().string(from: Date()), "type": another_param_type, "unit": another_unit_value, "note": another_note ?? "", "recorder_method": "device", "meta_data": metaData ] as [String: Any] // 组装成多对象数组 let arrayOfObjects = [param1, param2] var request = URLRequest(url: url! ) request.httpMethod = "POST" request.setValue(strToken, forHTTPHeaderField: "Header") // 必须添加该请求头,告知API请求体为JSON格式 request.setValue("application/json", forHTTPHeaderField: "Content-Type") // 安全序列化JSON,避免强制try崩溃 do { request.httpBody = try JSONSerialization.data(withJSONObject: arrayOfObjects, options: []) } catch { print("JSON序列化失败:\(error)") return } AF.request(request) .responseJSON { response in switch response.result { case .failure(let error): print(error) case .success(let responseObject): print(responseObject) } }
修正方案2:使用Codable模型+JSONEncoder(推荐,类型更安全)
通过定义模型类/结构体,避免手动构建字典时的字段遗漏和类型错误:
// 定义符合JSON结构的数据模型 struct DataRecord: Codable { let value: String let recordedAt: String let type: String let unit: String let note: String let recorderMethod: String let metaData: [String: String] // 映射JSON字段名与模型属性名 enum CodingKeys: String, CodingKey { case value case recordedAt = "recorded_at" case type case unit case note case recorderMethod = "recorder_method" case metaData = "meta_data" } } // 创建模型实例 let record1 = DataRecord( value: dataValue, recordedAt: ISO8601DateFormatter().string(from: Date()), type: paramValueType, unit: unitValue, note: addNote ?? "", recorderMethod: "device", metaData: [ "additionalProp1": "value1", "additionalProp2": "value2" ] ) let record2 = DataRecord( value: another_data_value, recordedAt: ISO8601DateFormatter().string(from: Date()), type: another_param_type, unit: another_unit_value, note: another_note ?? "", recorderMethod: "device", metaData: [ "additionalProp1": "value3" ] ) // 组装成模型数组 let records = [record1, record2] var request = URLRequest(url: url! ) request.httpMethod = "POST" request.setValue(strToken, forHTTPHeaderField: "Header") request.setValue("application/json", forHTTPHeaderField: "Content-Type") // 使用JSONEncoder编码模型数组 do { request.httpBody = try JSONEncoder().encode(records) } catch { print("模型编码失败:\(error)") return } AF.request(request) .responseJSON { response in switch response.result { case .failure(let error): print(error) case .success(let responseObject): print(responseObject) } }
内容的提问来源于stack exchange,提问作者Kshitij876
相关产品推荐
相关产品推荐

