如何在Swift中使用multipart参数上传图片并传递指定请求参数
Swift 原生 Multipart/Form-Data 图片上传实现
以下代码可直接复用,支持同时添加普通文本参数和图片文件参数:
import Foundation import UIKit func uploadImage(url: URL, parameters: [String: String], image: UIImage, imageKey: String, fileName: String, mimeType: String = "image/jpeg", completion: @escaping (Data?, URLResponse?, Error?) -> Void) { // 生成唯一边界标识 let boundary = "Boundary-\(UUID().uuidString)" var request = URLRequest(url: url) request.httpMethod = "POST" request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") var body = Data() // 拼接普通文本参数 for (key, value) in parameters { body.append("--\(boundary)\r\n".data(using: .utf8)!) body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n".data(using: .utf8)!) body.append("\(value)\r\n".data(using: .utf8)!) } // 拼接图片文件参数 guard let imageData = image.jpegData(compressionQuality: 0.8) else { completion(nil, nil, NSError(domain: "ImageError", code: -1, userInfo: [NSLocalizedDescriptionKey: "图片转换失败"])) return } body.append("--\(boundary)\r\n".data(using: .utf8)!) body.append("Content-Disposition: form-data; name=\"\(imageKey)\"; filename=\"\(fileName)\"\r\n".data(using: .utf8)!) body.append("Content-Type: \(mimeType)\r\n\r\n".data(using: .utf8)!) body.append(imageData) body.append("\r\n".data(using: .utf8)!) // 写入结束边界 body.append("--\(boundary)--\r\n".data(using: .utf8)!) request.httpBody = body URLSession.shared.dataTask(with: request, completionHandler: completion).resume() }
使用示例
// 替换为实际接口地址 guard let uploadUrl = URL(string: "https://你的接口域名/upload") else { return } // 按接口要求填写普通参数 let params = [ "user_id": "10001", "file_sort": "avatar" ] // 替换为需要上传的图片 let targetImage = UIImage(named: "test_image")! uploadImage(url: uploadUrl, parameters: params, image: targetImage, imageKey: "file", fileName: "avatar_10001.jpg") { data, response, error in if let error = error { print("上传失败:\(error.localizedDescription)") return } guard let httpRes = response as? HTTPURLResponse, httpRes.statusCode == 200 else { print("接口状态异常") return } if let data = data, let result = try? JSONSerialization.jsonObject(with: data) { print("上传成功:\(result)") } }
Alamofire 简化实现(项目已集成Alamofire时使用)
import Alamofire // 返回结构根据实际接口字段调整 struct UploadResult: Codable { let code: Int let message: String let data: FileInfo? } struct FileInfo: Codable { let url: String } func afUpload(url: String, params: [String: String], image: UIImage) { AF.upload(multipartFormData: { formData in // 添加普通参数 for (k, v) in params { formData.append(v.data(using: .utf8)!, withName: k) } // 添加图片 guard let imgData = image.jpegData(compressionQuality: 0.8) else { return } formData.append(imgData, withName: "file", fileName: "upload.jpg", mimeType: "image/jpeg") }, to: url).responseDecodable(of: UploadResult.self) { response in switch response.result { case .success(let res): print(res) case .failure(let error): print(error) } } }
注意事项
- 图片参数的
name字段必须和接口要求的文件参数名完全一致 - 多图上传只需循环拼接多个文件段即可
- 边界使用UUID生成可避免和参数内容冲突
- 可根据需求调整图片压缩质量、MIME类型(如png对应
image/png)
内容的提问来源于stack exchange,提问作者Rahul
相关产品推荐
相关产品推荐

