From 74d478f5ac26ec6b033fafe35b02eee347b664f0 Mon Sep 17 00:00:00 2001 From: joywayer Date: Sat, 27 Jun 2026 21:19:37 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=9E=E9=80=80=20IPA=20=E5=8D=87=E7=BA=A7?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=20exit(0)=EF=BC=9Aitms-services=20=E5=AE=89?= =?UTF-8?q?=E8=A3=85=E5=BC=B9=E7=AA=97=E9=9C=80=20source=20app=20=E5=9C=A8?= =?UTF-8?q?=E5=86=85=E5=AD=98=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 【bug】 上个 commit (b548039) 在跳 Safari 后等 didEnterBackground 自动 exit(0), 实测后果是 iOS 系统级"安装"确认弹窗根本不弹了 —— 整个升级链路被悄悄中断。 【根因】 iOS 的 itms-services:// URL scheme 启动系统安装确认弹窗时,依赖 source app 仍在内存里(安全机制:只允许有效 source app 触发系统级安装流程)。我们提前 exit 后,Safari 收到 URL 但系统拒绝弹确认窗。 【方案】 不再自动 exit。让 App 自然留在后台,iOS 在 IPA 替换时会自动结束旧进程 (或要求用户上滑),无需主动介入。 【UX】 alert 文案重新写成"前往下载"+"安装确认弹窗出现后请点击「安装」,等待下载 完成即可自动替换",对齐 iOS 实际安装流程。 代码注释里写清楚为什么不能 exit,避免未来再踩同一坑。 Co-Authored-By: Claude Opus 4.7 --- .../WebView/WebContainerViewController.swift | 36 +++++++------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/ylgamehall/Source/WebView/WebContainerViewController.swift b/ylgamehall/Source/WebView/WebContainerViewController.swift index 866e443..e511f57 100644 --- a/ylgamehall/Source/WebView/WebContainerViewController.swift +++ b/ylgamehall/Source/WebView/WebContainerViewController.swift @@ -549,35 +549,23 @@ public final class WebContainerViewController: UIViewController { } private func showIPAUpgradeAlert(downloadURL: String) { + // ⚠️ 不要在跳 Safari 后自动 exit(0): + // iOS 的 itms-services:// 系统安装确认弹窗依赖 source app 仍在内存中 + // 才能弹出(系统安全机制);提前 exit 会让 Safari 收到 URL 但确认窗 + // 不显示,整个安装流程被悄悄中断。 + // + // 正确做法:跳 Safari 后让 App 自然留在后台。用户在 Safari 点「安装」 + // 后,iOS 开始下载 → 替换 IPA 时会自动结束旧 App 进程(或要求用户上滑), + // 无需主动介入。 let alert = UIAlertController( title: "需要升级", - message: "检测到新版本,确认后将跳转下载并自动退出当前 App。", + message: "检测到新版本,点击「前往下载」开始更新。\n\n安装确认弹窗出现后请点击「安装」,等待下载完成即可自动替换。", preferredStyle: .alert ) - alert.addAction(UIAlertAction(title: "确定", style: .default) { _ in - guard let url = URL(string: downloadURL) else { return } - // 用户从 Safari 点"安装"完成 IPA 替换时,iOS 要求旧版本 App 不在运行 - // —— 若旧 App 仍在前/后台 active,"安装"按钮会卡住或要求用户手动 kill。 - // - // 解法:跳 Safari 后等 App 真正 didEnterBackground 再 exit(0) - // - 等系统进入后台 = iOS 已完成 active → inactive → background 切换,再 exit 不会被视为 crash - // - 比直接 exit(0) 优雅:避免前台用户看到"闪退"动画 / Springboard 记 crash - // - 一次性 observer,触发后立即 remove;用户从 Safari 取消回来不退(下次切后台才退) - var observerHandle: NSObjectProtocol? - observerHandle = NotificationCenter.default.addObserver( - forName: UIApplication.didEnterBackgroundNotification, - object: nil, - queue: .main - ) { _ in - if let h = observerHandle { - NotificationCenter.default.removeObserver(h) - } - // 给 iOS 0.3s 完成"进入后台"动画与状态保存,避免 SIGTERM 太快引起异常报告 - DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { - exit(0) - } + alert.addAction(UIAlertAction(title: "前往下载", style: .default) { _ in + if let url = URL(string: downloadURL) { + UIApplication.shared.open(url) } - UIApplication.shared.open(url) }) present(alert, animated: true) }