我相信没有合法的方法可以真正解决这个问题。 Apple 不希望应用程序在后台执行操作,因为后台活动会消耗大量电池,并且可能会让 iPhone 用户感觉电池续航时间不够(此外还有“无法解释的”网络使用等其他问题) ,因此为了用户体验,他们仅提供有关 iOS 应用程序后台活动的非常有限的选项。但是,我们可以通过某些方式使应用程序保持活动状态:
来自iOS 应用程序编程指南 https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html:
当您发现有必要让应用程序在后台运行时,iOS 可以帮助您高效地完成此操作,并且不会耗尽系统资源或用户的电池。 iOS 提供的技术分为三类:
- 在前台启动短任务的应用程序可以在应用程序移至后台时请求时间来完成该任务。
- 在前台启动下载的应用程序可以将对这些下载的管理移交给系统,从而允许应用程序在下载继续时暂停或终止。
- 需要在后台运行以支持特定类型的应用程序
任务可以声明支持一个或多个后台执行
模式。
如此看来,除了要求iOS允许应用程序完成短任务或下载之外,请求系统允许应用程序在后台运行的唯一方法就是在我们的程序中指定后台执行模式。Info.plist
。这可以在 XCode 中完成Capabilities
对话框,或直接编辑属性列表文件。让我们检查一下我们有哪些可用的后台执行模式:
在 iOS 中,只允许特定的应用程序类型在后台运行:
- 在后台向用户播放音频内容的应用程序,例如音乐播放器应用程序
- 在后台录制音频内容的应用程序
- 让用户随时了解其位置的应用程序,例如导航应用程序
- 支持互联网语音协议 (VoIP) 的应用
- 需要定期下载和处理新内容的应用
- 从外部配件接收定期更新的应用程序
保持套接字处于活动状态可能属于“需要定期下载和处理新内容的应用程序”用例,所以让我们检查一下:
机会主义地获取少量内容
需要定期检查新内容的应用程序可以要求系统唤醒它们,以便它们可以启动该内容的获取操作。要支持此模式,请从 Xcode 项目中“功能”选项卡的“后台模式”部分启用“后台获取”选项。 (您还可以通过在应用程序的 Info.plist 文件中包含带有提取值的 UIBackgroundModes 键来启用此支持。)启用此模式并不能保证系统会给您的应用程序任何时间执行后台提取。系统必须平衡应用程序获取内容的需求与其他应用程序和系统本身的需求。评估这些信息后,系统会在有合适的机会时为应用程序提供时间。
因此,此选项似乎仅适用于通过 HTTP 请求(或其他网络请求)获取少量内容,不适用于 websocket 允许您使用的双向持续通信。事实上,看着其他相关答案 https://stackoverflow.com/questions/8261135/how-to-keep-iphone-ios-xmpp-connection-alive-while-in-the-background/11022682#11022682,当应用程序进入后台模式时,似乎确实没有合法的方式来保持套接字打开。
这意味着,要执行您想要的操作,您不能使用 Websocket 作为唯一的通信渠道。我建议您使用fetch
后台模式(如上所述),以便在应用程序处于后台时获取比使用 websocket 更大的块内容,或者如果您希望用户能够看到新内容可用,您可以实现推送通知 https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html#//apple_ref/doc/uid/TP40008194-CH8-SW1.
您不能使用推送通知直接发送大量内容,但它们可以用于提示用户在打开您的应用程序时有新内容可用。无论您使用后台获取还是推送通知,您都应该在应用程序委托上实现方法,每当您的应用程序从后台状态恢复时,该方法都会将应用程序的状态与后端的状态同步。
最后,关于使用音频作为解决方法:audio
背景状态键将允许您的应用程序在后台无限期地保持活动状态 - 但如果您的应用程序没有真正使用它来播放音频,那么它will被应用商店拒绝。