iOS端上传图片与JSON至后端时图片无法被接收的技术求助
上传图片与JSON到后端时后端无法获取图片的解决方案
问题根源
你的代码中处理图片二进制数据的逻辑存在错误:在ChamaDataField函数里,你将图片的二进制Data通过String(data: data, encoding: .utf8)转换为字符串,再转回Data。但图片的二进制内容并非合法的UTF-8编码文本,这个转换过程会导致数据丢失或损坏,最终后端接收到的图片数据是无效的,自然无法正确解析。
修复方案
重构图片字段的拼接逻辑,直接操作二进制数据,避免字符串转换带来的损坏:
修改后的代码
// 重构图片字段拼接函数,直接返回Data而非String func chamaDataField(fieldName: String, fileName: String, data: Data, mimeType: String) -> Data { var body = Data() // 添加边界和头部信息 body.append("--\(boundary)\r\n".data(using: .utf8)!) body.append("Content-Disposition: form-data; name=\"\(fieldName)\"; filename=\"\(fileName)\"\r\n".data(using: .utf8)!) body.append("Content-Type: \(mimeType)\r\n\r\n".data(using: .utf8)!) // 直接添加图片二进制数据,不做字符串转换 body.append(data) body.append("\r\n".data(using: .utf8)!) return body } func chamaTextField(named name: String, value: String) -> Data { var fieldString = "" fieldString += "--\(boundary)\r\n" fieldString += "Content-Disposition: form-data; name=\"\(name)\"\r\n\r\n" fieldString += value fieldString += "\r\n" return Data(fieldString.utf8) } private func myFormDataCallTwo(requestBody model: chamaOfficialsPhotoUploadRequestTwo, documentName: String, documentData: UIImage?, _ completion: @escaping (Bool, String?) -> ()) { let baseUrl = "https://mbankingtest.postbank.co.ke:9193/" let endpointPath = "mchama/api/gateway/files" guard let url = URL(string: baseUrl + endpointPath) else { completion(false, "Invalid URL") return } var request = URLRequest(url: url) guard let sessionValue = AppConfig.AppStore["sessionId"] as? String else { print("Failed to retrieve session ID") completion(false, nil) return } request.setValue(sessionValue, forHTTPHeaderField: "session_id") request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") request.httpMethod = "POST" var body = Data() guard let documentsData = documentData else { completion(false, "document data is nil") return } guard let imageData = documentsData.jpegData(compressionQuality: 0.7) else { completion(false, "Failed to convert UIImage to Data") return } guard let jsonData = try? JSONEncoder().encode(model) else { completion(false, "Failed to encode model to json") return } // 使用重构后的函数拼接图片字段 body.append(chamaDataField(fieldName: "files", fileName: "\(documentName).jpg", data: imageData, mimeType: "image/jpeg")) let imageHex = imageData.prefix(20).map { String(format: "%02x", $0) }.joined() print("Image Data (first 20 bytes as hex): \(imageHex)") // 拼接JSON字段 guard let jsonString = String(data: jsonData, encoding: .utf8) else { completion(false, "Failed to convert JSON data to string") return } body.append(chamaTextField(named: "data", value: jsonString)) // 闭合表单 body.append("--\(boundary)--\r\n".data(using: .utf8)!) // Debug: Print JSON data print("JSON being sent: \(jsonString)") // Debug: Print final assembled body in chunks let bodyStringComponents = [ String(data: body.prefix(100), encoding: .utf8) ?? "", "..." ] print("Request body: \(bodyStringComponents.joined())") request.httpBody = body for (key, value) in request.allHTTPHeaderFields ?? [:] { print("My Header - \(key) : \(value)") } if let bodyString = String(data: body, encoding: .utf8) { print("Request body: \(bodyString)") } let session = URLSession.shared session.dataTask(with: request) {(data, response, error) in if let error = error { completion(false, error.localizedDescription) return } if let response = response { print("Response: \(response)") } if let data = data { do { let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] if let dataValue = jsonObject?["data"] as? String { print("Document was uploaded successfully. identifier: \(dataValue)") completion(true, dataValue) } else { print("Document uploaded successfully but failed to parse response") completion(true, nil) } } catch { print("Error decoding JSON response: \(error)") completion(false, error.localizedDescription) } } else { completion(false, "No response data received") } }.resume() }
额外说明
- 确保
boundary是一个唯一的随机字符串,比如用UUID().uuidString生成,避免和请求内容中的字符串冲突 - 修复后,图片的二进制数据会完整传递到后端,后端就能正确解析出图片文件
- 完善了错误处理逻辑,在JSON转字符串失败时直接返回错误,避免强制解包崩溃
内容的提问来源于stack exchange,提问作者Collins Muthomi
相关产品推荐
相关产品推荐

