URLSession 仅在手机网络上神秘失败

问题描述 投票:0回答:1

这样打的电话

let jsonData = try JSONSerialization.data(withJSONObject: requestBody)
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData

let (data, response) = try await URLSession.shared.data(for: request)

当我从模拟器中调用它时,它在 100% 的时间里都能完美运行。

当我在 WiFi 上的手机上运行它时,它 100% 完美运行。

但是当我在手机网络上运行它时。它失败随机.

但是如果我尝试使用手机上的另一个 API 测试应用程序调用该端点。它有效。

失败时返回的错误如下:

Error Domain=NSURLErrorDomain Code=-1005 “网络连接是 丢失了。” UserInfo={_kCFStreamErrorCodeKey=57, NSUnderlyingError=0x28198df50 {错误域=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={NSErrorPeerAddressKey={length = 28, capacity = 28, bytes = 0x1c1e01bb000000002606470000200000 ... 681a00aa00000000}, _kCFStreamErrorCodeKey=57, _kCFStreamErrorDomainKey=1}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask .<2>, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask .<2>" ), NSLocalizedDescription=网络连接丢失。, NSErrorFailingURLStringKey=https://blahblah/v1/run, NSErrorFailingURLKey=https://blahblah/v1/run, _kCFStreamErrorDomainKey=1}

swift nsurlconnection nsurlsession urlsession
1个回答
0
投票

你的 POST body 有多大?蜂窝网络有时会很不稳定,上传大文件时失去连接也很常见。

如果您要上传大块数据,一个好的策略是更改服务器端以允许您以块的形式上传数据,重试每个块直到成功,然后在完成所有内容的上传后在服务器端合并这些块.

否则,你应该问的下一个问题是你是否可以使请求幂等。如果有可能以发送两次不会造成任何伤害的方式发出请求,那么您应该使用 GET 请求,以便 NSURLSession 机制可以在某些类型的网络故障、网络更改后重试请求,等等 POST 请求是never retried.

你应该问的第三件事是你是否正在使用回调覆盖任何会话的行为。如果是这样,您确定每次都在调用提供的回调吗?我见过的一些常见错误包括:

  • 未能为您不关心的类型的证书/密码/身份验证请求调用默认处理。
  • 进行 NSURLConnection 样式的调用以继续请求而不是调用回调(有时会,但并不总是有效)。
  • 在做一些其他事情后存储回调以调用,然后有时调用失败。
  • 从与被调用队列不同的调度队列调用回调(这可能没问题,但 IIRC 过去常常导致问题)。
  • 配置会话使用并发 NSOperation 队列。 😁
  • 阻塞/死锁会话用于调度回调的队列。

等等。这些事情中的任何一个都可能导致非常奇怪的行为。

除此之外,寻找您在有效应用程序和无效应用程序之间设置会话和连接的方式的任何差异——会话配置的差异、共享缓存配置的差异、任务创建的差异,线程模型等方面的差异

祝你好运。

© www.soinside.com 2019 - 2024. All rights reserved.