Alamofire 上传失败,文件超过 1MB

Posted

技术标签:

【中文标题】Alamofire 上传失败,文件超过 1MB【英文标题】:Alamofire upload failing with file over 1MB 【发布时间】:2021-09-13 15:56:38 【问题描述】:

在将音频文件上传到服务器时,我正在努力解决在 Swift 5 中使用 Alamofire 的问题。 如果文件大小为 1MB 或更小,一切都很好,但只要文件大于 1MB,它似乎就会超时,但我无法确定问题是 Alamofire 还是服务器端。 上传失败时,控制台报如下错误;

2021-09-13 10:36:26.966452-0500 App Name[32446:2616254] Task <EFF172FB-4FD0-4857-8727-84D91F6C06A9>.<1> HTTP load failed, 1048956/463 bytes (error code: -1017 [4:-1])
2021-09-13 10:36:26.970745-0500 App Name[32446:2617311] Task <EFF172FB-4FD0-4857-8727-84D91F6C06A9>.<1> finished with error [-1017] Error Domain=NSURLErrorDomain Code=-1017 "cannot parse response" UserInfo=_kCFStreamErrorCodeKey=-1, NSUnderlyingError=0x6000011fa940 Error Domain=kCFErrorDomainCFNetwork Code=-1017 "(null)" UserInfo=NSErrorPeerAddressKey=<CFData 0x600003c7f390 [0x7fff8004b340]>length = 16, capacity = 16, bytes = 0x100201bbd82eb8f90000000000000000, _kCFStreamErrorCodeKey=-1, _kCFStreamErrorDomainKey=4, _NSURLErrorFailingURLSessionTaskErrorKey=LocalUploadTask <EFF172FB-4FD0-4857-8727-84D91F6C06A9>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalUploadTask <EFF172FB-4FD0-4857-8727-84D91F6C06A9>.<1>"
), NSLocalizedDescription=cannot parse response, NSErrorFailingURLStringKey=https://<server and endpoint>, NSErrorFailingURLKey=https://<server and endpoint>, _kCFStreamErrorDomainKey=4

我已尝试调试,但无法弄清楚,正在寻找任何建议。这是代码;

fileprivate func UploadAudio(_ todaysDate: String) -> DataRequest 
        return AF.upload(multipartFormData:  [self] multipartFormData in
        multipartFormData.append(finalFilename, withName: "audio", fileName: "final.wav", mimeType: "audio/x-wav")
        ,to: Constants.getUrl()+"<api endpoint>").debugLog().authenticate(username: defaults.string(forKey: "username")!, password: defaults.string(forKey: "password")!)
        .uploadProgress  progress in // main queue by default
            self.progressView!.progress = Float(progress.fractionCompleted)
            print("Upload Progress: \(progress.fractionCompleted)")
        
        .responseJSON  response in
            print("Here is audio submission form")
            print("Request: \(String(describing: response.request))")
            print("Response: \(String(describing: response.response))")
            print("Error: \(String(describing: response.error))")

            if(self.alertView != nil)
            
                self.alertView.dismiss(animated: true)
            
            if let audioLocation = response.response?.allHeaderFields["Location"] as? String 
                _ = self.StartTranscription(audioLocation)
            
            else
            
                self.showAlert(title: "Alert", message: "Couldn't get the location URL")
            
        
    

同样,如果音频文件小于 1MB,它可以正常上传,我得到一个有效的 JSON 响应,一切都很好。

提前致谢。

【问题讨论】:

服务器出现什么错误? @EmilioPelaez 这不是我的服务器,所以我无法得到任何未返回响应的错误。我与服务器管理员交谈,他们说该端点上没有任何限制应该会影响这一点。 @RyanH - 尽管他们说他们没有限制,但他们是否检查了您的请求是否有任何错误?我之前遇到过类似的问题,一旦他们检查了服务器日志,我们发现这是他们的问题。 @MwcsMac 我刚刚通过使用不同的 API 将端点更改为另一台服务器进行了测试,如果文件超过 1MB,我也会收到错误发送,所以这似乎是我的问题Alamofire 代码不知何故。我尝试使用 PCM 文件和 m4a 并得到相同的结果。我检查了我们服务器上的 php 日志,没有错误。我 100% 知道,我们的服务器使用该 API 支持最多 150MB 的上传,并且经常从上传页面使用。 关于我之前的评论。我确实犯了一个错误。由于与 API 无关的不同错误,它在我们的服务器上失败。我已经能够在那里上传大于 1MB 的文件,所以看起来它实际上可能是服务器上的问题.... 【参考方案1】:

这最终成为 Alamofire 的一个问题。我们不得不切换到 URL Session,然后我们就完全没有问题了。 这并不能解释问题实际上是什么,但它与 Alamofire 有关。 OP 中发布的代码不起作用,但以下代码按预期工作;

        if(self.progressView != nil)
        
            self.progressView.progress  = Float(Float(totalBytesSent) / Float(totalBytesExpectedToSend))
        
    
    
    var urlSession = URLSession.shared
    
    func sendPostRequest(
        to url: URL,
        filePath: String,
        then handler: @escaping (Result<Data, Error>) -> Void
    ) 
        var body:Data? = nil
        body = try? Data(contentsOf: URL(fileURLWithPath: filePath))
        var request = URLRequest(
            url: url,
            cachePolicy: .reloadIgnoringLocalCacheData
        )
        
        request.httpMethod = "POST"
        
        let task = urlSession.uploadTask(
            with: request,
            from: body,
            completionHandler:  data, response, error in
                // Validate response and call handler
                
            
        )
        
        task.resume()
    

我不知道这是否会帮助任何人,但我想发布它是如何解决的,以防其他人遇到同样的问题。

【讨论】:

以上是关于Alamofire 上传失败,文件超过 1MB的主要内容,如果未能解决你的问题,请参考以下文章

上传文件失败,具体原因:上传的文件超过大小限制,请上传小于 1024k的文件?

Nginx PHP 上传大文件失败(超过 6 GB)

使用 Alamofire 上传图像不成功

Alamofire 4 - 使用 gzip 编码上传多部分

大文件上传失败的php

如何快速修复成功和失败案例的 Alamofire 5 错误?