使用 Alamofire 上传 MultipartFormData
MultipartFormData upload using Alamofire
我一直在尝试使用 Alamofire 实现多部分表单数据。
我编写了一些代码,它非常适合执行时间低于 60 秒的请求。但是,如果请求花费的时间超过这个时间,它就会结束并且上传不会完成:
此外,我得到了这个输出(可能意味着我的应用程序正在尝试写入一个关闭的 TCP 套接字):
2017-06-20 17:22:21.924948 app[4645:1381848] [] nw_endpoint_flow_prepare_output_frames [110.1 10.39.80.102:8550 ready socket-flow (satisfied)] Failed to use 1 frames, marking as failed
2017-06-20 17:22:21.928262 app[4645:1381848] [] nw_endpoint_handler_add_write_request [110.1 10.39.80.102:8550 failed socket-flow (satisfied)] cannot accept write requests
2017-06-20 17:22:21.929278 app[4645:1381027] [] __tcp_connection_write_eof_block_invoke Write close callback received error: [22] Invalid argument
我已经尝试通过更改 timeoutIntervalForRequest
和 timeoutIntervalForResource
参数来修改我用来执行请求的 URLSessionConfiguration
:
func initManager(timeoutInterval:Double) {
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = timeoutInterval
configuration.timeoutIntervalForResource = timeoutInterval
alamofireManager = Alamofire.SessionManager(configuration: configuration)
}
但是,我仍然遇到同样的问题。有谁知道如何解决这个问题?或者有人遇到同样的问题吗?
谢谢
您可能在服务器端达到了执行时间限制。也就是说,我认为 iOS 10.0 – 10.2.x 中还有一个错误可能会导致这种不当行为。 (更多内容在 https://forums.developer.apple.com/thread/67606。)
即使您解决了这个特定问题的原因,这里的根本问题还是设计问题,而不是请求本身的问题。网络不可靠,蜂窝网络更是如此。保持蜂窝连接超过一分钟的几率与中彩票的几率大致相同。 (是的,这是夸张,但你明白了。)
我建议采用以下替代方法:
- POST 或 PUT 端点,它采用文件名、数据流和写入字节的可选偏移量。
- 一个单独的 POST 端点,用于处理使用上述端点上传的文件。
- 一个单独的 GET 端点,returns 指定上传文件的当前大小。
然后,在客户端开始上传。如果上传由于任何原因失败,您将在文件大小端点上发出 GET,并发出一个新的 POST 并将偏移设置为文件长度后的第一个字节(并仅提供上传数据的最后一部分, 显然).
无论连接失败是由于 iOS 中的错误、服务器配置错误还是随机网络故障,这都可以避免丢失上传的单个字节。更好的是,它也可能与 NSURLSession 中的后台上传一起工作。
我一直在尝试使用 Alamofire 实现多部分表单数据。 我编写了一些代码,它非常适合执行时间低于 60 秒的请求。但是,如果请求花费的时间超过这个时间,它就会结束并且上传不会完成:
此外,我得到了这个输出(可能意味着我的应用程序正在尝试写入一个关闭的 TCP 套接字):
2017-06-20 17:22:21.924948 app[4645:1381848] [] nw_endpoint_flow_prepare_output_frames [110.1 10.39.80.102:8550 ready socket-flow (satisfied)] Failed to use 1 frames, marking as failed
2017-06-20 17:22:21.928262 app[4645:1381848] [] nw_endpoint_handler_add_write_request [110.1 10.39.80.102:8550 failed socket-flow (satisfied)] cannot accept write requests
2017-06-20 17:22:21.929278 app[4645:1381027] [] __tcp_connection_write_eof_block_invoke Write close callback received error: [22] Invalid argument
我已经尝试通过更改 timeoutIntervalForRequest
和 timeoutIntervalForResource
参数来修改我用来执行请求的 URLSessionConfiguration
:
func initManager(timeoutInterval:Double) {
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = timeoutInterval
configuration.timeoutIntervalForResource = timeoutInterval
alamofireManager = Alamofire.SessionManager(configuration: configuration)
}
但是,我仍然遇到同样的问题。有谁知道如何解决这个问题?或者有人遇到同样的问题吗?
谢谢
您可能在服务器端达到了执行时间限制。也就是说,我认为 iOS 10.0 – 10.2.x 中还有一个错误可能会导致这种不当行为。 (更多内容在 https://forums.developer.apple.com/thread/67606。)
即使您解决了这个特定问题的原因,这里的根本问题还是设计问题,而不是请求本身的问题。网络不可靠,蜂窝网络更是如此。保持蜂窝连接超过一分钟的几率与中彩票的几率大致相同。 (是的,这是夸张,但你明白了。)
我建议采用以下替代方法:
- POST 或 PUT 端点,它采用文件名、数据流和写入字节的可选偏移量。
- 一个单独的 POST 端点,用于处理使用上述端点上传的文件。
- 一个单独的 GET 端点,returns 指定上传文件的当前大小。
然后,在客户端开始上传。如果上传由于任何原因失败,您将在文件大小端点上发出 GET,并发出一个新的 POST 并将偏移设置为文件长度后的第一个字节(并仅提供上传数据的最后一部分, 显然).
无论连接失败是由于 iOS 中的错误、服务器配置错误还是随机网络故障,这都可以避免丢失上传的单个字节。更好的是,它也可能与 NSURLSession 中的后台上传一起工作。