当前位置: 首页 > 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.dtcms.com/a/349695.html

相关文章:

  • springboot中操作redis的步骤
  • 6.4 Element UI 中的 <el-table> 表格组件
  • 疯狂星期四文案网第49天运营日记
  • 疯狂星期四文案网第50天运营日记
  • 渗透测试报告编写平台 | 简化和自动化渗透测试报告的生成过程。
  • JVM 与容器化部署优化:突破资源隔离的性能瓶颈
  • Ant Design for UI 选择下拉框
  • 详细介绍Vue-Router及其实现原理、路由模式
  • 探索汽车材料新纪元:AUTO TECH 2025广州先进汽车材料展即将震撼来袭
  • Linux系统编程——进程 | 线程
  • SSM基础知识-SpringMVC-视图解析(ModelAndView)、方法请求参数接收、方法返回值处理、RESTful 风格、拦截器、全局异常
  • UniApp文件上传大小限制问题解决方案
  • Mysql 5.7 与 SqlSugar 5.X 整合开发实战
  • 对线性代数伴随矩阵的深刻理解
  • ComfyUI AI一键换装工作流无私分享
  • 【ansible】6.主机模式以及包含和导入文件
  • Ansible自动化运维介绍与安装
  • 国内代理 IP 的类型:住宅 IP、机房 IP、移动 4G/5G IP 区别
  • 愿景娱乐:践行“流量向善”以公益行动赋能“她”未来
  • RAG(知识库ChatPDF)
  • 开源大模型天花板?DeepSeek-V3 6710亿参数MoE架构深度拆解
  • 无障碍辅助模块|Highcharts引领可访问数据可视化的交流
  • 部分CSS笔试题讲解
  • Python JSON 全方位解析:序列化、反序列化与实战技巧
  • pytest+requests+Python3.7+yaml+Allure+Jenkins+docker实现接口自动化测试
  • k8sday17安全机制
  • flask Celery入门:轻松实现异步任务处理
  • 前端通过node本地转译rtsp流,配合hls实现浏览
  • 【SQL】深入理解MySQL存储过程:从入门到实战
  • CUDA 工具包 13.0 正式发布:开启新一代 GPU 计算的基石!