Swift 4中如何在HTTP Body同时发送字符串与JSON值
解决方案:在请求体中同时发送字符串和JSON数据
我猜你是想把两个独立的字符串值,和一个由AttendancePost结构体序列化后的JSON对象,一起打包到同一个HTTP请求体里发送给后端对吧?下面给你两种在Swift中常用的实现方案,你可以根据后端的接口要求来选择:
方案一:打包成单一JSON对象(推荐,大多数REST接口用这种)
如果后端期望接收一个完整的JSON对象,里面包含你的两个字符串字段和嵌套的考勤数据,我们可以定义一个顶层的结构体来包裹所有内容,然后统一序列化为JSON:
// 先定义一个顶层请求结构体,包含你需要的两个字符串和AttendancePost对象 struct AttendanceRequest: Codable { // 这里替换成你实际需要的两个字符串字段名 let customString1: String let customString2: String let attendance: AttendancePost } // 构建你的AttendancePost实例(注意:尽量避免强制解包,这里给你优化下) guard let acadID = data.acad_id, let stdID = data.stdid else { print("缺少必要的acad_id或stdid数据") return } let attendanceData = AttendancePost( acad_id: acadID, school_id: SCHOOL_ID, class_id: self.classFID, section_id: self.secID, stdid: stdID, status: "1", attendant_id: "你的attendant_id值" // 这里替换成实际值 ) // 构建完整的请求体对象 let requestBody = AttendanceRequest( customString1: "第一个字符串的值", customString2: "第二个字符串的值", attendance: attendanceData ) // 序列化为JSON数据并发送请求 do { let jsonData = try JSONEncoder().encode(requestBody) var request = URLRequest(url: URL(string: "你的API接口地址")!) request.httpMethod = "POST" request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type") request.httpBody = jsonData let task = URLSession.shared.dataTask(with: request) { data, response, error in // 处理请求响应 if let error = error { print("请求失败:\(error.localizedDescription)") return } // 解析响应数据(如果需要的话) if let responseData = data { do { // 替换成你的响应模型类型 let response = try JSONDecoder().decode(YourResponseModel.self, from: responseData) print("请求成功:\(response)") } catch { print("响应解析失败:\(error)") } } } task.resume() } catch { print("JSON序列化失败:\(error.localizedDescription)") }
方案二:使用Multipart/Form-Data格式
如果后端要求用表单形式接收数据(比如一个字段是字符串,另一个字段是JSON格式的参数),可以用multipart/form-data来拆分不同的参数:
// 同样先构建AttendancePost实例 guard let acadID = data.acad_id, let stdID = data.stdid else { print("缺少必要的acad_id或stdid数据") return } let attendanceData = AttendancePost( acad_id: acadID, school_id: SCHOOL_ID, class_id: self.classFID, section_id: self.secID, stdid: stdID, status: "1", attendant_id: "你的attendant_id值" ) // 把AttendancePost序列化为JSON数据 let jsonAttendanceData = try JSONEncoder().encode(attendanceData) // 构建multipart请求 let boundary = "FormBoundary-\(UUID().uuidString)" var request = URLRequest(url: URL(string: "你的API接口地址")!) request.httpMethod = "POST" request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") var bodyData = Data() // 添加第一个字符串字段 bodyData.append("--\(boundary)\r\n".data(using: .utf8)!) bodyData.append("Content-Disposition: form-data; name=\"customString1\"\r\n\r\n".data(using: .utf8)!) bodyData.append("第一个字符串的值\r\n".data(using: .utf8)!) // 添加第二个字符串字段 bodyData.append("--\(boundary)\r\n".data(using: .utf8)!) bodyData.append("Content-Disposition: form-data; name=\"customString2\"\r\n\r\n".data(using: .utf8)!) bodyData.append("第二个字符串的值\r\n".data(using: .utf8)!) // 添加JSON格式的考勤数据字段 bodyData.append("--\(boundary)\r\n".data(using: .utf8)!) bodyData.append("Content-Disposition: form-data; name=\"attendance\"\r\n".data(using: .utf8)!) bodyData.append("Content-Type: application/json\r\n\r\n".data(using: .utf8)!) bodyData.append(jsonAttendanceData) bodyData.append("\r\n".data(using: .utf8)!) // 结束boundary bodyData.append("--\(boundary)--\r\n".data(using: .utf8)!) request.httpBody = bodyData // 发送请求 let task = URLSession.shared.dataTask(with: request) { data, response, error in if let error = error { print("请求失败:\(error.localizedDescription)") return } // 处理响应逻辑 if let responseData = data { // 解析响应内容 } } task.resume()
注意事项
- 避免强制解包:你原来代码里的
data.acad_id!和data.stdid!容易导致崩溃,建议用guard let或者空合运算符??来处理可选值。 - 字段名要匹配:确保你定义的结构体字段名和后端接口要求的字段名完全一致,如果不一致可以用
CodingKeys来映射。 - 确认后端格式:先和后端确认接口接收的是JSON对象还是multipart表单,选错格式会导致请求失败。
内容的提问来源于stack exchange,提问作者TheSwiftGuy77
相关产品推荐
相关产品推荐

