【问题标题】:Alamofire upload failing with file over 1MBAlamofire 上传失败,文件超过 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 的文件,所以看起来它实际上可能是服务器上的问题....

标签: swift alamofire


【解决方案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()
    }

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

【讨论】:

    最近更新 更多