You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 11:45:04