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

Swift中如何解析Alamofire返回的multipartFormData响应

解决Alamofire解析Multipart响应的问题

你已经成功发送了Multipart请求,服务器也返回了包含JSON和WAV的Multipart响应,但Alamofire默认的responseString这类方法并不会帮你自动拆分Multipart格式的内容——我们得手动解析这个响应,把JSON和WAV文件分别提取出来。

核心思路

  1. 从响应头的Content-Type里提取boundary(Multipart内容的分隔符,这是拆分内容的关键)
  2. 把响应的Data按boundary拆分成多个子数据块
  3. 逐个识别每个数据块的类型(JSON/WAV),分别处理对应内容

完整代码示例

把你原来的upload.responseString替换成下面的处理逻辑:

upload.responseData { response in
    // 先确保能拿到响应数据和Content-Type头
    guard let responseData = response.data, 
          let contentTypeHeader = response.response?.allHeaderFields["Content-Type"] as? String else {
        print("获取响应数据或Content-Type失败")
        return
    }
    
    // 从Content-Type中提取boundary
    let boundaryPrefix = "boundary="
    guard let boundaryRange = contentTypeHeader.range(of: boundaryPrefix) else {
        print("无法从响应头中找到boundary")
        return
    }
    let boundary = "--" + contentTypeHeader[boundaryRange.upperBound...].trimmingCharacters(in: .whitespacesAndNewlines)
    
    // 用boundary拆分整个响应数据
    let dataParts = responseData.split(separator: Data(boundary.utf8), omittingEmptySubsequences: true)
    
    // 遍历每个数据块,分别处理JSON和WAV
    for part in dataParts {
        // 每个数据块的结构是:头部信息 + 空行(\r\n\r\n) + 实际内容
        guard let headerEndIndex = part.range(of: Data("\r\n\r\n".utf8))?.upperBound else {
            continue
        }
        let headerData = part[..<headerEndIndex]
        let contentData = part[headerEndIndex...]
        
        // 解析头部,判断当前块是JSON还是WAV
        if let headerStr = String(data: headerData, encoding: .utf8), headerStr.contains("application/json") {
            // 处理JSON部分
            do {
                let jsonResult = try JSONSerialization.jsonObject(with: contentData, options: [])
                print("解析到JSON数据:", jsonResult)
                // 这里可以把jsonResult转换成你需要的模型对象
            } catch {
                print("JSON解析失败:", error)
            }
        } else if let headerStr = String(data: headerData, encoding: .utf8), headerStr.contains("audio/wav") {
            // 处理WAV文件部分,这里示例是保存到沙盒的Documents目录
            let docsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
            let saveUrl = docsDir.appendingPathComponent("AudioFromTts.wav")
            do {
                try contentData.write(to: saveUrl)
                print("WAV文件已保存至:", saveUrl.path)
                // 你也可以直接用contentData播放音频,不需要保存
            } catch {
                print("保存WAV文件失败:", error)
            }
        }
    }
}

关键细节说明

  • 拆分Multipart内容的核心是boundary,它会在响应头的Content-Type里以boundary=xxx的形式存在,我们需要把它提取出来并加上前缀--才能作为拆分符
  • 每个数据块的头部包含了该块的类型信息(比如Content-Type: application/json),通过判断这个信息就能区分JSON和WAV部分
  • 如果你需要把JSON转换成自定义模型,可以用JSONDecoder替代JSONSerialization,适配你的业务需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:52:33