
swift ui 如何使用Alamofire上传文件,并且附带formData参数
作者: boyyang
分类: Swift
发布: 2025-05-16 09:18:13
更新: 2025-05-16 09:32:57
浏览: 111
背景
最近在使用swift ui开发ios原生应用,由于使用的是Alamofire向后端请求数据,一般的get,post请求都还正常,但是当我需要上传图片的时候,我查了一下文档,Alamofire是有提供formData上传文件的。文件上传是解决了,但是我该怎么在上传文件的同时附带额外的参数呢,比如说文件上传到后端的哪个储存桶,文件压缩质量等等。这个时候我就不知道该怎么处理了。
在此之前先介绍一下Alamofire是什么吧。
Alamofire是什么
Alamofire 是一个用于 Swift 编程语言的强大且流行的 HTTP 网络库。它由 Alamofire 团队开发和维护,旨在简化网络请求的处理,使开发者能够更高效地进行网络编程。
主要特点包括:
- 简洁易用:Alamofire 提供了简洁的 API,使得发送 HTTP 请求变得非常简单。
- 功能强大:支持各种 HTTP 方法(GET、POST、PUT、DELETE 等),以及多种数据传输方式(JSON、URL 编码、多部分表单等)。
- 错误处理:提供了详细的错误处理机制,帮助开发者快速定位和解决问题。
- 链式调用:支持链式调用,使得请求配置和响应处理更加灵活。
- 支持多种数据格式:支持 JSON、XML、Plist 等多种数据格式。
- 后台任务支持:可以在后台线程中执行网络请求,不会阻塞主线程。
- 安全性:支持 HTTPS,并且可以配置 SSL/TLS 以确保数据传输的安全性。
Alamofire如何使用
使用 Alamofire 进行网络请求非常简单。以下是一个基本的 GET 请求示例:
首先,确保你已经将 Alamofire 添加到你的项目中。如果你使用的是 Swift Package Manager,可以在 Package.swift
文件中添加 Alamofire 依赖(我是之间通过git仓库地址在xcode里面直接搜索添加到项目中的):
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "YourProjectName",
dependencies: [
.package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.4.3")
],
targets: [
.target(
name: "YourTargetName",
dependencies: ["Alamofire"])
]
)
具体使用:
import Alamofire
Alamofire.request("https://api.example.com/data")
.responseJSON { response in
switch response.result {
case .success(let value):
if let json = value as? [String: Any] {
print("JSON: \(json)")
}
case .failure(let error):
print("Error: \(error)")
}
}
如何上传文件
//
// UPLOAD.swift
// Unsplash
//
// Created by boyyang on 2025/4/29.
//
import SwiftUI
import Alamofire
public struct UploadRes: Decodable {
var id: String
var file_name: String
var path: String
var origin_path: String
}
public struct AlamofireAsync {
@AppStorage("token") var token: String = ""
static let shared = AlamofireAsync()
let uploadUrl = "http://localhost:8888/image/upload/bytes"
func request(file: Data, fileName: String, dir: String, type: String) async throws -> Response<UploadRes> {
return try await withCheckedThrowingContinuation { continuation in
let headers: HTTPHeaders = [
"Content-type": "multipart/form-data",
"Authorization": token,
]
AF.upload(
multipartFormData: {multipartFormData in
multipartFormData.append(file, withName: "file", mimeType: "image")
multipartFormData.append(fileName.data(using: .utf8, allowLossyConversion: false)!, withName: "file_name")
multipartFormData.append("wallpaper".data(using: .utf8, allowLossyConversion: false)!, withName: "bucket_name")
multipartFormData.append("IMAGES".data(using: .utf8, allowLossyConversion: false)!, withName: "root_dir")
multipartFormData.append(dir.data(using: .utf8, allowLossyConversion: false)!, withName: "dir")
multipartFormData.append("10".data(using: .utf8, allowLossyConversion: false)!, withName: "quality")
multipartFormData.append("1".data(using: .utf8, allowLossyConversion: false)!, withName: "status")
multipartFormData.append(type.data(using: .utf8, allowLossyConversion: false)!, withName: "type")
},
to: uploadUrl,
method: .post ,
headers: headers,
).responseDecodable(of: Response<UploadRes>.self) { res in
switch res.result {
case .success(let resp):
continuation.resume(returning: resp)
case .failure(let err):
continuation.resume(throwing: err)
}
}
}
}
值得一提的是如果你想在上传文件的同时附带一下参数,你得通过multipartFormData.append("IMAGES".data(using: .utf8, allowLossyConversion: false)!, withName: "root_dir")
这种方式上传额外的参数,withName就是上传参数的名称,前面的是上传参数的值。我之前就是把这2个给搞反了,导致我的后端一直获取不到参数,我还在到处寻找问题。