diff --git a/ylgamehall/Source/WebView/WebContainerViewController.swift b/ylgamehall/Source/WebView/WebContainerViewController.swift index 60c3fd9..e0b7e21 100644 --- a/ylgamehall/Source/WebView/WebContainerViewController.swift +++ b/ylgamehall/Source/WebView/WebContainerViewController.swift @@ -554,26 +554,44 @@ public final class WebContainerViewController: UIViewController { } private func showIPAUpgradeAlert(downloadURL: String) { - // 行为目标:点「确定」直接弹系统安装窗(不跳 Safari),用户点「安装」后 - // App 自然切后台、用户看到桌面图标下载进度,App 进程留在内存,无需主动 exit。 + // 行为目标:点「确定」直接弹系统安装窗 + App 自动切后台(用户回到桌面), + // 用户在桌面上点「安装」即可看到 App 图标下载进度,App 进程留在内存不退出。 // - // 实现依赖:URL 必须是 iOS 可直接接管的安装协议(itms-services 或 manifest plist 直链)。 - // 详见 makeInstallURL 注释。如果远端配的是 https 网页链接,仍会跳 Safari - // 给用户看引导页 —— 这是预期外的情形,需后台把 appDownload 改成 itms-services - // 或 .plist 直链才能跳过 Safari 中转。 + // iOS 实际行为:调 itms-services 时系统弹安装确认窗,但本 App 仍处于 inactive + // 状态(弹窗是模态覆盖在 App 上),用户点「安装」后弹窗 dismiss、App 回到 active + // —— 系统**不会主动**切后台。要让用户回桌面,需要本 App 主动调私有 selector + // `suspend` 把自己切后台(等价于用户按 Home / 上滑)。 + // 本项目企业签 / 渠道分发,不上架 AppStore,可以用私有 API。 + // + // URL 形态:itms-services 直链 / .plist 直链 / 其它(Safari)—— 详见 makeInstallURL。 + // Safari 路径不调 suspend:用户已经在 Safari,suspend 反而破坏 Safari 引导页体验。 let alert = UIAlertController( title: "需要升级", message: "检测到新版本,点击「确定」开始升级,系统会自动下载并安装。", preferredStyle: .alert ) alert.addAction(UIAlertAction(title: "确定", style: .default) { _ in - if let url = Self.makeInstallURL(from: downloadURL) { - UIApplication.shared.open(url) + guard let url = Self.makeInstallURL(from: downloadURL) else { return } + UIApplication.shared.open(url) + if url.scheme?.lowercased() == "itms-services" { + // 0.3s 等系统接收 itms-services URL(确认弹窗 schedule 完成), + // 然后把 App 切后台。系统弹窗仍会覆盖在桌面上正常显示。 + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { + Self.suspendAppToHomeScreen() + } } }) present(alert, animated: true) } + /// 把本 App 切到后台(用户看到桌面),App 进程留在内存。 + /// 私有 selector `suspend` 等价于按 Home / 上滑回桌面的系统行为。 + /// `UIControl.sendAction` 内部会处理 selector 不响应的情况,比 `perform()` 安全。 + private static func suspendAppToHomeScreen() { + let sel = NSSelectorFromString("suspend") + UIControl().sendAction(sel, to: UIApplication.shared, for: nil) + } + /// 把远端 `appDownload` 规范化为 iOS 系统可直接接管的安装协议,避免跳 Safari 中转。 /// /// 三种 raw URL 形态: