当前位置: 首页 > news >正文

将跨平台框架或游戏引擎开发的 macOS 应用上架 Mac App Store

随着 macOS 用户数量的增长,越来越多的开发者希望将自己的桌面应用或游戏上架到 Mac App Store,以便触达更多用户并获得官方的分发优势。但 Apple 的上架流程相比其他平台要严格得多,涉及签名、打包、沙盒、审核、公证等环节。本文将以博文的形式,详细梳理常见跨平台框架(Flutter / Electron / Qt / Tauri / Python)以及游戏引擎(Unity / Unreal / Godot)的 打包、签名、公证与上架流程


A. Mac App Store 与非商店分发的区别

1. Mac App Store (MAS)

  • 分发产物:.pkg(Product Archive)
  • 必须:App 沙盒 + 正确的签名(Apple Distribution / 3rd Party Mac Developer Installer)
  • 上传方式:Transporter(GUI)、Xcode OrganizeriTMSTransporter CLI
  • 公证(Notarization):不需要开发者自己跑,Apple 在审核过程中会自动完成。

2. 非商店分发(官网直下 / 第三方渠道)

  • 分发产物:.dmg / .zip / .pkg
  • 必须:Developer ID 签名 + Hardened Runtime
  • 还需:Notarization 公证 + Stapler 钉票,才能通过 Gatekeeper 校验。

B. 核心步骤总览

Mac App Store 流程

  1. 生成 .app
  2. 签名(Apple Distribution)
  3. 打包 .pkg(productbuild)
  4. Transporter / Xcode 上传 App Store Connect

非商店分发流程

  1. 生成 .app
  2. 签名(Developer ID Application + Hardened Runtime)
  3. 打包(.dmg / .zip / .pkg
  4. notarytool submit 公证
  5. stapler staple 钉票
  6. spctl --assess 自测

C. 各平台构建方式

1) Flutter(macOS 桌面)

flutter config --enable-macos-desktop
flutter build macos --release
# 输出: build/macos/Build/Products/Release/MyApp.app
  • MAS:签名 → productbuild → Transporter 上传
  • 非商店:签名 → 打包 .dmg/.pkg → 公证 + stapler

2) Electron

# MAS 构建
electron-builder --mac mas# 非商店构建 (DMG)
electron-builder --mac dmg
  • 提供 entitlements.mas.plist / entitlements.mas.inherit.plist
  • MAS 签名 & 沙盒要求较高

3) Qt(C++ / PyQt / PySide)

# 生成 .app
depoyqt MyApp.app -appstore-compliant
  • MAS:签名 → productbuild → Transporter 上传
  • 非商店:签名 → dmg/pkg → 公证

4) Tauri

cargo tauri build
  • 输出 universal2 .app
  • MAS / 非商店均按签名 & 打包流程继续

5) Python(PyInstaller / py2app)

# PyInstaller universal2
pyinstaller --windowed --target-arch universal2 main.py
# 输出 dist/MyApp.app# py2app\python3
setup.py py2app
  • MAS:签名(Apple Distribution)→ productbuild → Transporter
  • 非商店:签名(Developer ID)→ dmg/pkg → 公证

6) Unity

# Build Settings → Platform: macOS → Build
# 输出: MyGame.app
  • MAS:签名 .appproductbuild → Transporter
  • 非商店:签名 → 打包 .dmg → 公证 + stapler

7) Unreal Engine

# File → Package Project → macOS
# 输出: MyUnrealGame.app
  • 后续步骤与 Unity 相同

8) Godot

# Editor → Export → macOS → MyGodotGame.zip
  • MAS:解压 zip → 签名 .app → productbuild
  • 非商店:签名 → zip/dmg → 公证

D. 签名与打包命令示例

签名(MAS - Apple Distribution)

codesign --deep --force --timestamp \--entitlements Entitlements.plist \--sign "Apple Distribution: Your Name (TEAMID)" \"MyApp.app"productbuild \--component "MyApp.app" /Applications \--product "MyApp.app/Contents/Info.plist" \--sign "3rd Party Mac Developer Installer: Your Name (TEAMID)" \"MyApp.pkg"

签名(非商店 - Developer ID + Hardened Runtime)

codesign --deep --force --timestamp \--options runtime \--entitlements Entitlements.plist \--sign "Developer ID Application: Your Name (TEAMID)" \"MyApp.app"

公证 + Staple

xcrun notarytool submit MyApp.dmg \--apple-id "your@appleid.com" \--team-id "TEAMID" \--password "app-specific-password" \--waitxcrun stapler staple MyApp.dmgspctl --assess --type install -vv MyApp.dmg

E. 常见 Entitlements 配置(MAS 必须)

<dict><key>com.apple.security.app-sandbox</key><true/><key>com.apple.security.network.client</key><true/><key>com.apple.security.files.user-selected.read-write</key><true/>
</dict>

F. 审核前自检清单

  • ✅ App 使用 Universal Binary (x86_64 + arm64)
  • ✅ 正确的 版本号分类 (LSApplicationCategoryType)
  • ✅ 沙盒权限最小化
  • ✅ 签名验证通过 (codesign -dv, pkgutil --check-signature)
  • ✅ (非商店)公证 + stapler 成功

总结

  • 上架 MAS:签名(Apple Distribution)→ productbuild → Transporter → 审核(Apple 自动公证)
  • 非商店分发:签名(Developer ID + Hardened Runtime)→ 打包 → 公证 (notarytool) → stapler → Gatekeeper 校验

掌握这些步骤,你就能让 Flutter 应用、Electron 桌面端、Qt 工具、Tauri 应用、Python 应用,甚至 Unity/Unreal/Godot 游戏,顺利通过 Apple 的严格审查,上架 Mac App Store 或安全分发给用户。

http://www.xdnf.cn/news/1362259.html

相关文章:

  • Docker基本使用方法和常用命令
  • 8851定期复盘代码实现设计模式的于芬应用
  • 从2D序列帧到3D体积感:我用AE+UE5 Niagara构建次世代风格化VFX工作流
  • TDengine IDMP 应用场景:IT 系统监控
  • Ubuntu 14.10 i386桌面版安装教程(U盘启动详细步骤-附安装包下载)​
  • 800G时代!全场景光模块矩阵解锁数据中心超高速未来
  • 5分钟发布技术博客:cpolar简化Docsify远程协作流程
  • Zabbix企业级监控运维实践为主(新)
  • ╳╳╳╳╳╳╳╳╳╳头像商店╳╳╳╳╳╳╳╳╳╳
  • 独立显卡接口操作指南
  • blazor 学习笔记--vscode debug
  • 探索汽车材料新纪元:AUTO TECH 2025广州先进汽车材料展即将震撼来袭
  • Vim 的 :term命令:终端集成的终极指南
  • 服务器Docker 安装和常用命令总结
  • 零售收银选乐檬,高市占率背后的全链路价值赋能
  • 【SQL】深入理解MySQL存储过程:从入门到实战
  • Linux / 宝塔面板下 PHP OPcache 完整实践指南
  • 当模型学会集思广益:集成学习的核心原理与多样化协作模式解析
  • 【Hadoop】HDFS 分布式存储系统
  • 数据结构:单链表(详解)
  • Linux-Redis的安装
  • 【Linux】开发工具命令指南:深度解析Vim的使用操作
  • Java项目-苍穹外卖_Day1
  • 计算机毕业设计 java 血液中心服务系统 基于 Java 的血液管理平台Java 开发的血液服务系统
  • 【应急响应工具教程】Unix/Linux 轻量级工具集Busybox
  • 页面中嵌入Coze的Chat SDK
  • (多线程)线程安全和线程不安全 产生的原因 synchronized关键字 synchronized可重入特性死锁 如何避免死锁 内存可见性
  • 前端通过node本地转译rtsp流,配合hls实现浏览
  • Go语言运算符全解析
  • 用 fastmcp 2.0 做一个“短期记忆(Redis)”的 MCP 服务器(Server)+ 一个简单的 Client 例子