如何通过Apple API在macOS上以编程方式更新Mac App Store应用
实现Mac App Store应用程序化更新的官方方案
问题根源
softwareupdate命令行仅负责系统更新、Apple VPP分发的企业应用,普通用户从App Store下载的第三方应用不在其管理范畴,这就是你遇到部分应用无法更新的原因。而App Store的资源下载需要绑定Apple ID的会话验证,临时链接无法通过curl直接获取,苹果也未开放这类直接下载的API。
官方唯一可行方案:StoreKit for macOS
苹果提供的StoreKit框架是macOS平台上唯一官方认可的、可集成App Store应用更新逻辑的工具,支持原生macOS应用或Mac Catalyst应用。
核心实现步骤
配置应用权限
- 在Xcode中开启App Sandbox,勾选
Network > Outgoing Connections (Client),确保应用能连接App Store服务器。 - 原生macOS应用需在entitlements文件中添加
com.apple.security.network.client权限。
- 在Xcode中开启App Sandbox,勾选
查询应用更新状态
通过SKStoreProductRequest获取目标应用的App Store版本信息,与本地已安装版本对比:import StoreKit func checkAppUpdate(forBundleID bundleID: String) { let request = SKStoreProductRequest(productIdentifier: bundleID) request.delegate = self request.start() } extension YourToolClass: SKStoreProductRequestDelegate { func productRequest(_ request: SKStoreProductRequest, didReceive response: SKProductsResponse) { guard let appProduct = response.products.first else { print("Failed to fetch app info from App Store") return } // 获取本地已安装应用的版本号 guard let installedVersion = Bundle(identifier: bundleID)?.infoDictionary?["CFBundleShortVersionString"] as? String else { print("Cannot get installed app version") return } // 对比版本号(需自行实现语义化版本比较逻辑) if isNewerVersion(appProduct.version, than: installedVersion) { triggerUpdateFlow(for: appProduct) } } } // 示例版本号比较函数 func isNewerVersion(_ appStoreVersion: String, than installedVersion: String) -> Bool { let appStoreComponents = appStoreVersion.split(separator: ".").compactMap(Int.init) let installedComponents = installedVersion.split(separator: ".").compactMap(Int.init) for (a, i) in zip(appStoreComponents, installedComponents) { if a > i { return true } if a < i { return false } } // 若前面版本号相同,App Store版本更长则视为更新 return appStoreComponents.count > installedComponents.count }触发更新流程
苹果不允许第三方应用静默更新App Store应用,必须引导用户完成交互。你可以选择两种方式:- 应用内打开App Store更新页面:
func triggerUpdateFlow(for product: SKProduct) { let storeVC = SKStoreProductViewController() storeVC.delegate = self let params = [SKStoreProductParameterITunesItemIdentifier: product.productIdentifier] storeVC.loadProduct(withParameters: params) { [weak self] success, _ in if success { self?.present(storeVC, animated: true) } else { self?.openAppStoreDirectly(for: product) } } } - 直接跳转系统App Store应用:
func openAppStoreDirectly(for product: SKProduct) { if let appStoreURL = URL(string: "itms-apps://apps.apple.com/app/id\(product.productIdentifier)") { NSWorkspace.shared.open(appStoreURL) } }
- 应用内打开App Store更新页面:
关键限制
- 所有更新必须经过用户交互确认,无法实现静默更新(苹果沙盒与安全机制要求)。
- StoreKit 2需要macOS 12+,若需支持更低版本,需使用旧版StoreKit API。
- 必须知道目标应用的Bundle ID才能查询其更新状态。
内容的提问来源于stack exchange,提问作者user21500026
相关产品推荐
相关产品推荐

