iOS Swift使用WKWebView时出现RBS Background assertion报错问题
根因说明
你遇到的报错本质是WKWebView独立的WebContent进程在后台被系统回收导致:
RBS Background assertion ‘ConnectionTerminationWatchdog’ for process because PID is invalid[Process] 0x11630be18 - [pageProxyID=14, webPageID=15, PID=3281] WebPageProxy::processDidTerminate: (pid 3281), reason 3
Error acquiring assertion: <Error Domain=RBSAssertionErrorDomain Code=3 “Target is not running or required target entitlement is missing”...>
WKWebView的JS执行、页面渲染逻辑都运行在独立于App主进程的WebContent进程中,当WKWebView不在前台视图层级、且App处于半后台/后台状态时,系统会主动暂停甚至销毁WebContent进程节省资源,此时你向WKWebView发送通信请求时,对应PID的进程已经不存在,就会触发断言错误导致崩溃。
排查修复步骤
- 步骤1:新增WebContent进程存活校验,避免调用已销毁的进程
首先实现WKNavigationDelegate的webViewWebContentProcessDidTerminate代理方法,监听进程销毁事件做标记:
func webViewWebContentProcessDidTerminate(_ webView: WKWebView) { // 标记进程已销毁,后续通信前先检查该标记 UserDefaults.standard.set(false, forKey: "web_process_alive") }
每次需要向WKWebView通信前,先执行轻量探测校验进程状态:
func checkWebProcessAlive(completion: @escaping (Bool) -> Void) { webView.evaluateJavaScript("1") { _, error in completion(error == nil) } }
如果探测返回false,不要执行后续通信逻辑,先走进程恢复流程。
- 步骤2:短时间后台交互场景,申请临时后台权限保活
如果你的原生处理流程耗时不超过30秒,可以在切出WKWebView页面时申请临时后台任务权限,避免WebContent进程被提前回收:
var bgTaskId: UIBackgroundTaskIdentifier = .invalid // 切走WKWebView页面时调用 bgTaskId = UIApplication.shared.beginBackgroundTask(withName: "WKWebViewKeepAlive") { // 后台时间到了主动结束任务 UIApplication.shared.endBackgroundTask(self.bgTaskId) self.bgTaskId = .invalid } // 完成和WKWebView的通信后主动调用结束任务 if bgTaskId != .invalid { UIApplication.shared.endBackgroundTask(bgTaskId) bgTaskId = .invalid }
- 步骤3:进程销毁后的自动恢复
如果探测到WebContent进程已销毁,先调用reload()方法重新拉起进程,等页面加载完成后再执行通信逻辑:
// 进程已销毁时先重载页面 webView.reload() // 在navigationDelegate的didFinish代理回调中再执行数据回传逻辑
- 步骤4:优先选择前台通信方案(最稳定)
如果原生处理流程耗时较长,不要强行在后台执行通信,先把需要回传的数据存在本地内存/持久化存储,等上层视图控制器关闭、WKWebView重新回到前台可见状态时,再读取缓存的数据执行JS通信,完全规避后台进程被回收的问题。
注意事项
不要使用私有API强制保持WebContent进程后台存活,该类实现会被App Store审核拒绝。
内容的提问来源于stack exchange,提问作者Saad Rafique

