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

iOS:非Multipart方式上传大JSON文件的进度追踪问题

如何用Alamofire追踪JSON请求体的上传进度

当然可以实现!虽然Alamofire的常规JSON POST请求(比如直接传parameters的方式)不会暴露上传阶段的进度,但我们可以换个巧妙的思路绕过去——核心是先把包含base64图片的JSON序列化为Data,再用Alamofire的upload方法发送这个Data,这样既能保留JSON请求体的格式,又能利用uploadProgress闭包追踪上传进度。

具体步骤和代码示例

  1. 序列化JSON请求体并计算总字节数
    首先把你的参数(包括base64编码的图片)转成JSON Data,这样我们能提前知道要上传的总数据大小,这是追踪进度的关键:

    // 假设你已经将UIImage转为base64字符串
    let imageBase64 = "your-base64-image-string"
    let uploadParams: [String: Any] = [
        "image": imageBase64,
        "userId": 123,
        "description": "A test image"
    ]
    
    // 序列化为JSON Data
    guard let jsonData = try? JSONSerialization.data(withJSONObject: uploadParams, options: []) else {
        print("JSON序列化失败")
        return
    }
    
    let totalUploadBytes = jsonData.count
    
  2. 用Alamofire的upload方法发送Data并追踪进度
    用upload方法直接上传这个JSON Data,同时设置正确的Content-Type头(确保服务器识别为JSON请求),然后通过uploadProgress闭包获取实时进度:

    AF.upload(jsonData, to: "https://your-api-endpoint.com/upload")
        // 手动设置Content-Type为application/json,确保服务器正确解析
        .setHeader(name: "Content-Type", value: "application/json")
        .validate()
        .uploadProgress { progress in
            // 这里获取实时上传进度
            let progressPercentage = progress.fractionCompleted * 100
            print("上传进度: \(String(format: "%.2f", progressPercentage))%")
            // 可以在这里更新UI,比如进度条的progress值
        }
        .responseJSON { response in
            switch response.result {
            case .success(let responseData):
                print("上传成功,响应数据: \(responseData)")
                // 处理成功逻辑
            case .failure(let error):
                print("上传失败,错误信息: \(error.localizedDescription)")
                // 处理错误逻辑
            }
        }
    

为什么这个方案可行?

Alamofire的upload方法是专门为追踪上传进度设计的——不管你上传的是本地文件还是内存中的Data,它都会基于URLSession的任务进度回调,实时返回已发送字节数和总字节数。而我们提前序列化好JSON Data,就相当于把整个请求体变成了一个"虚拟文件"来上传,既满足了服务器对JSON请求体的要求,又能拿到上传进度。

注意事项

  • 内存占用问题:base64编码后的图片会比原图片大33%左右,如果你的图片很大,序列化后的JSON Data可能会占用较多内存。如果遇到内存警告,可以考虑优化图片尺寸后再编码,或者和后端沟通是否支持分块上传(虽然你说不支持multipart,但分块上传可能是另一种方案)。
  • Content-Type头:一定要手动设置application/json,否则Alamofire默认可能会把Data的Content-Type设为application/octet-stream,导致服务器无法正确解析JSON。

内容的提问来源于stack exchange,提问作者swalkner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:55:22