跳到主要内容

Mac App Store 提交指南

本指南提供以下信息:

  • 如何在 macOS 上签名 Electron 应用;
  • 如何将 Electron 应用提交到 Mac App Store (MAS);
  • MAS 版本的局限性。

要求

要签名 Electron 应用,必须首先安装以下工具

  • Xcode 11 或更高版本。
  • @electron/osx-sign npm 模块。

您还必须注册一个 Apple Developer 帐户并加入 Apple Developer Program

签名 Electron 应用

Electron 应用可以通过 Mac App Store 或在外部进行分发。每种方式都需要不同的签名和测试方法。本指南侧重于通过 Mac App Store 分发。

以下步骤描述了如何从 Apple 获取证书、如何签名 Electron 应用以及如何测试它们。

获取证书

获取签名证书的最简单方法是使用 Xcode

  1. 打开 Xcode 并打开“帐户”偏好设置;
  2. 使用您的 Apple 帐户登录;
  3. 选择一个团队并单击“管理证书”;
  4. 在签名证书表的左下角,单击添加按钮 (+),并添加以下证书
    • Apple Development
    • Apple Distribution

“Apple Development”证书用于在已在 Apple Developer 网站上注册的计算机上签名用于开发和测试的应用。注册方法将在准备 Provisioning Profile中描述。

使用“Apple Development”证书签名的应用无法提交到 Mac App Store。为此,应用必须改为使用“Apple Distribution”证书签名。但请注意,使用“Apple Distribution”证书签名的应用无法直接运行,它们必须由 Apple 重新签名才能运行,这只有在从 Mac App Store 下载后才有可能。

其他证书

您可能会注意到还有其他类型的证书。

“Developer ID Application”证书用于在 Mac App Store 外部发布应用之前对其进行签名。

“Developer ID Installer”和“Mac Installer Distribution”证书用于签名 Mac Installer Package 而不是应用本身。大多数 Electron 应用不使用 Mac Installer Package,因此通常不需要它们。

证书类型的完整列表可以在这里找到。

使用“Apple Development”和“Apple Distribution”证书签名的应用只能在 App Sandbox 下运行,因此它们必须使用 Electron 的 MAS 版本。但是,“Developer ID Application”证书没有此限制,因此使用它签名的应用可以使用普通版本或 Electron 的 MAS 版本。

旧版证书名称

Apple 在过去几年中一直在更改证书的名称,您在阅读旧文档时可能会遇到它们,并且一些实用程序仍在使用的旧名称之一。

  • “Apple Distribution”证书也曾被命名为“3rd Party Mac Developer Application”和“Mac App Distribution”。
  • “Apple Development”证书也曾被命名为“Mac Developer”和“Development”。

准备 Provisioning Profile

如果您想在将应用提交到 Mac App Store 之前在本地计算机上测试您的应用,则必须使用嵌入在应用捆绑包中的 Provisioning Profile 和“Apple Development”证书对应用进行签名。

创建 Provisioning Profile,您可以按照以下步骤操作

  1. Apple Developer 网站上打开“Certificates, Identifiers & Profiles”页面。
  2. 在“Identifiers”页面中为您的应用添加新的 App ID。
  3. 在“Devices”页面中注册您的本地计算机。您可以在“系统信息”应用的“硬件”页面中找到您计算机的“设备 ID”。
  4. 在“Profiles”页面中注册新的 Provisioning Profile,并将其下载到 `/path/to/yourapp.provisionprofile`。

启用 Apple 的 App Sandbox

提交到 Mac App Store 的应用必须在 Apple 的 App Sandbox 下运行,并且只有 Electron 的 MAS 版本才能在 App Sandbox 下运行。标准的 darwin 版 Electron 在 App Sandbox 下运行时将无法启动。

当使用 `@electron/osx-sign` 签名应用时,它会自动将必要的授权添加到您应用的授权中。

不使用 electron-osx-sign 的额外步骤

如果您在不使用 `@electron/osx-sign` 的情况下签名您的应用,则必须确保应用捆绑包的授权至少具有以下键

entitlements.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>TEAM_ID.your.bundle.id</string>
</array>
</dict>
</plist>

`TEAM_ID` 应替换为您的 Apple Developer 帐户的 Team ID,`your.bundle.id` 应替换为应用的 App ID。

以下授权必须添加到应用捆绑包中的二进制文件和助手

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.inherit</key>
<true/>
</dict>
</plist>

并且应用捆绑包的 `Info.plist` 必须包含 `ElectronTeamID` 键,该键的值为您的 Apple Developer 帐户的 Team ID

<plist version="1.0">
<dict>
...
<key>ElectronTeamID</key>
<string>TEAM_ID</string>
</dict>
</plist>

当使用 `@electron/osx-sign` 时,`ElectronTeamID` 键将通过从证书名称中提取 Team ID 自动添加。如果 `@electron/osx-sign` 找不到正确的 Team ID,您可能需要手动添加此键。

签名用于开发的应用

要签名一个可以在您的开发计算机上运行的应用,您必须使用“Apple Development”证书对其进行签名,并将 Provisioning Profile 传递给 `@electron/osx-sign`。

const { signAsync } = require('@electron/osx-sign')

signAsync({
app: '/path/to/your.app',
identity: 'Apple Development',
provisioningProfile: '/path/to/your.provisionprofile'
})

如果您在不使用 `@electron/osx-sign` 的情况下签名,则必须将 Provisioning Profile 放置到 `YourApp.app/Contents/embedded.provisionprofile`。

签名的应用只能在 Provisioning Profile 注册的计算机上运行,这是在提交到 Mac App Store 之前测试签名应用的唯一方法。

签名用于提交到 Mac App Store 的应用

要签名一个将提交到 Mac App Store 的应用,您必须使用“Apple Distribution”证书对其进行签名。请注意,使用此证书签名的应用将无法在任何地方运行,除非它是从 Mac App Store 下载的。

const { signAsync } = require('@electron/osx-sign')

signAsync({
app: 'path/to/your.app',
identity: 'Apple Distribution'
})

将应用提交到 Mac App Store

使用“Apple Distribution”证书签名应用后,您可以继续将其提交到 Mac App Store。

但是,本指南不保证您的应用会被 Apple 批准;您仍然需要阅读 Apple 的提交您的应用指南,了解如何满足 Mac App Store 的要求。

上传

应使用 Apple Transporter 将签名的应用上传到 App Store Connect 进行处理,确保您在上传之前已创建了记录

如果您看到诸如使用私有 API 之类的错误,则应检查应用是否正在使用 Electron 的 MAS 版本。

提交以供审核

上传后,您应该提交您的应用以供审核

MAS 版本的局限性

为了满足应用沙盒的所有要求,MAS 版本中已禁用以下模块

  • crashReporter
  • autoUpdater

并且以下行为已更改

  • 视频捕获可能在某些计算机上无法工作。
  • 某些辅助功能可能无法工作。
  • 应用将不会感知 DNS 更改。

此外,由于使用了应用沙盒,应用可以访问的资源受到严格限制;您可以阅读应用沙盒以获取更多信息。

其他授权

每个在 App Sandbox 下运行的应用都将在有限的权限集下运行,这限制了恶意代码的潜在危害。根据您的应用使用的 Electron API,您可能需要在您应用的授权文件中添加其他授权。否则,App Sandbox 可能会阻止您使用它们。

授权使用具有属性列表 (.plist) 或 XML 等格式的文件指定。您必须为应用程序捆绑包本身提供授权文件,并为所有其他封闭的可执行文件(如二进制文件、框架 (.framework) 和动态链接库 (.dylib))提供子授权文件,该文件基本上描述了属性的继承。

授权的完整列表可在 App Sandbox 文档中找到,但以下是您的 MAS 应用可能需要的一些授权。

使用 `@electron/osx-sign`,您可以按如下方式为每个文件设置自定义授权

const { signAsync } = require('@electron/osx-sign')

function getEntitlementsForFile (filePath) {
if (filePath.startsWith('my-path-1')) {
return './my-path-1.plist'
} else {
return './alternate.plist'
}
}

signAsync({
optionsForFile: (filePath) => ({
// Ensure you return the right entitlements path here based on the file being signed.
entitlements: getEntitlementsForFile(filePath)
})
})

网络访问

启用出站网络连接以允许您的应用连接到服务器

<key>com.apple.security.network.client</key>
<true/>

启用入站网络连接以允许您的应用打开网络监听套接字

<key>com.apple.security.network.server</key>
<true/>

有关更多详细信息,请参阅启用网络访问文档

dialog.showOpenDialog

<key>com.apple.security.files.user-selected.read-only</key>
<true/>

有关更多详细信息,请参阅启用用户选择的文件访问文档

dialog.showSaveDialog

<key>com.apple.security.files.user-selected.read-write</key>
<true/>

有关更多详细信息,请参阅启用用户选择的文件访问文档

Electron 使用的加密算法

根据您发布应用的国家/地区,您可能需要提供有关您的软件中使用的加密算法的信息。有关更多信息,请参阅加密出口合规性文档

Electron 使用以下加密算法