IPA 升级 URL 自动包成 itms-services:跳过 Safari、直接弹系统安装窗

【UX 目标】
点「确定」→ 直接弹系统安装确认窗(不跳 Safari)→ 用户点「安装」→
App 自然切后台、用户看到桌面图标下载进度,App 进程留在内存不退出。

【方案】
makeInstallURL 规范化 appDownload:
- itms-services://...        → 原样
- https?://...*.plist (mfst) → 包成 itms-services://?action=download-manifest&url=...
- 其它(网页 / 短链)         → 原样跳 Safari(后台需把 URL 改成上面两种之一才能跳过 Safari)

不再需要 exit(0);iOS 处理 itms-services 时本来就会把 App 切后台,自动满足用户
"回到桌面但 App 不退出"的需求。

文案改为"开始升级,系统会自动下载并安装"匹配新流程。

BuildProject 通过。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
joywayer
2026-06-27 21:46:43 +08:00
co-authored by Claude Opus 4.7
parent 692c849e0d
commit befe205bf9
@@ -554,27 +554,48 @@ public final class WebContainerViewController: UIViewController {
}
private func showIPAUpgradeAlert(downloadURL: String) {
// Safari exit(0)
// iOS itms-services:// source app
// exit Safari URL
//
// Safari
// App App exit
//
// Safari App Safari
// iOS IPA App
//
// URL iOS itms-services manifest plist
// makeInstallURL https Safari
// appDownload itms-services
// .plist Safari
let alert = UIAlertController(
title: "需要升级",
message: "检测到新版本,点击「确定」前往下载。\n\n安装确认弹窗出现后请点击「安装」,然后从多任务列表上滑退出本 App,更新即可自动完成",
message: "检测到新版本,点击「确定」开始升级,系统会自动下载并安装",
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "确定", style: .default) { _ in
if let url = URL(string: downloadURL) {
if let url = Self.makeInstallURL(from: downloadURL) {
UIApplication.shared.open(url)
}
})
present(alert, animated: true)
}
/// `appDownload` iOS Safari
///
/// raw URL
/// - `itms-services://...` iOS
/// - `https?://...*.plist` manifest
/// `itms-services://?action=download-manifest&url=<encoded>`iOS
/// - / Safari
/// URL Safari
private static func makeInstallURL(from raw: String) -> URL? {
let trimmed = raw.trimmingCharacters(in: .whitespaces)
let lower = trimmed.lowercased()
if lower.hasPrefix("itms-services://") {
return URL(string: trimmed)
}
if (lower.hasPrefix("https://") || lower.hasPrefix("http://")),
lower.hasSuffix(".plist") {
let encoded = trimmed.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? trimmed
return URL(string: "itms-services://?action=download-manifest&url=\(encoded)")
}
return URL(string: trimmed)
}
/// NWPath.unsatisfiedReason """"
/// iOS 14+ NSURLError -1009 path wifiDenied / cellularDenied
/// fallback NSURLError code