Error Domain=NSPOSIXErrorDomain Code=28 “No space left on device” UserInfo={_kCFStreamErrorCodeKey=28, _kCFStreamErrorDomainKey=1}

Error Domain=NSPOSIXErrorDomain Code=28 “No space left on device” UserInfo={_kCFStreamErrorCodeKey=28, _kCFStreamErrorDomainKey=1}

最近从我们的 iOS 设备发出的 Alamofire 的大量网络请求失败并出现以下错误:

Error Domain=NSPOSIXErrorDomain Code=28 "No space left on device" UserInfo={_NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask .<3>, _kCFStreamErrorDomainKey=1, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask .<3>" ), _kCFStreamErrorCodeKey=28}

如果用户移动了 +- 10 米,我们的应用程序会发送网络请求。这是每 5 秒检查一次,因此理论上每五秒可以进行一次调用。网络请求偶尔失败并显示此消息,不返回任何状态代码和上述错误。

该消息暗示错误与设备上的可用 disk/memory space 有关。但是,在检查两者之后,没有找到 link,因为有很多 space 可用。此外,错误发生在多个设备上,所有 运行 iOS 14.4 或更高版本。

是否有关于错误代码 28 的信息以及 iOS 设备上的罪魁祸首是什么?更好;如何避免此错误?

只是想补充更多信息,因为我们遇到了同样的问题。

根据我们的分析,此问题仅在 iOS 14 后才开始发生。我们已验证它发生在 14.2、14.4 和 14.5 上。自然地,导致此错误的最直接原因是内存或磁盘存储空间不足。我们已将此选项排除在附加日志记录之外,您似乎也这样做了。

可能 将问题归因于在其发布版本中启用的网络检查框架。如果您使用类似的工具,值得检查一下。

此问题的

Another report,这次是在 AFNetworking(您使用的 Alamofire 库的前身)的 Github 上,表示他们能够通过限制 URLSession 对象的创建来修复它。

就我们个人而言,这些都没有成功。我们与 Apple 一起创建了支持票,但这并没有带来解决方案。他们要求一个重现该问题的小型示例项目,但该错误仅在我们的应用程序连续使用 7 天后才出现。如果您有更快的方法来重现此内容,那么提交 your own support ticket.

可能是值得的

希望这可以帮助您找到解决方案,如果您这样做,请将其添加到您的 post 以帮助其他人!

回答错误本身的发生:

NSPOSIXErrorDomain Code=28 "No space left on device"

在 Xcode 终端中登录:

2021-05-07 15:56:50.873428+0200 MYAPP[21757:7406020] [] nw_path_evaluator_create_flow_inner NECP_CLIENT_ACTION_ADD_FLOW 05CD829A-810D-412F-B86E-7524369359E8 [28: No space left on device]

2021-05-07 15:56:50.877243+0200 MYAPP[21757:7400322] Task <5504BCDF-7DFE-4045-BD4B-E75054636D5B>.<1> finished with error [28] Error Domain=NSPOSIXErrorDomain Code=28 "No space left on device" UserInfo={_NSURLErrorFailingURLSessionTaskErrorKey=LocalUploadTask <5504BCDF-7DFE-4045-BD4B-E75054636D5B>.<1>, _kCFStreamErrorDomainKey=1, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalUploadTask <5504BCDF-7DFE-4045-BD4B-E75054636D5B>.<1>" ), _kCFStreamErrorCodeKey=28}

当创建的 NSURLSession 过多时,它似乎会被调用,达到(在我们的测试中)600-700 个会话的限制,这些会话未正确维护或关闭。从 iOS 14 开始出现错误,所以看看是否引入了限制很有趣。

Linked 是一个 github 问题,提出了 JetBrains 在 ktor 微服务框架上的相同问题,指向相同的方向,提到会​​话无效以防止此问题: https://github.com/ktorio/ktor/issues/1341

在我们自己的项目中,问题的根源原来是我们对 StarScream websocket 库的实现。这可能与其他人遇到的问题无关,但无论如何都要进行解释以创建问题的完整图片。这是我们特定情况的原因和解决方法。

起初我们假设它与 Alamofire(使用的网络库)创建的 URLSession 有关,因为 POST 请求开始被取消,而关闭应用程序似乎是处理请求的唯一解决方案再次.

但是,我们也使用 StarScream 库的 websocket 连接,它会尝试连接到套接字,如果失败,则每两秒重试连接一次,最长连接时间为两小时。这意味着在两个小时内,每两秒,我们连接到套接字 -> 收到连接失败 -> 断开套接字 -> 再次连接。使用套接字的单例被认为不可能创建多个 URLSession,因为套接字仅启动一次。然而,再次调用连接到套接字每次都会创建一个新的 nw_connection 对象,因为库没有正确处理断开连接。

image of NWConcrete_nw_connection objects generated in socket connection

验证方法是使用仪器应用程序检查是否创建了新的 nw_connection 对象。在那里记录为“内存泄漏”,nw_connection 对象的创建被记录下来,解决方案是确保我们在再次连接之前正确断开套接字(使会话无效)。

我希望能在这里回答大部分问题,我会将我自己的问题标记为已回答,因为这是手头问题的解决方案。我认为 Apple 应该考虑准确报告所创建对象的数量是有限的,而不是给出错误“No space left on device”。