跳转到主要内容

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 之外分发。每种方式都需要不同的签名和测试方法。本指南侧重于通过 Mac App Store 进行分发。

以下步骤将描述如何获取 Apple 的证书、如何对 Electron 应用进行签名以及如何测试它们。

获取证书

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

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

“Apple Development”证书用于在已注册到 Apple Developer 网站的机器上对应用进行开发和测试签名。“Prepare 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”页面注册您的本地机器。您可以在“System Information”应用程序的“Hardware”页面中找到您机器的“Device ID”。
  4. 在“Profiles”页面注册一个新的 Provisioning Profile,并将其下载到 /path/to/yourapp.provisionprofile

启用 Apple 的 App Sandbox

提交到 Mac App Store 的应用必须在 Apple 的 App Sandbox 下运行,并且只有 Electron 的 MAS 构建才能与 App Sandbox 一起运行。Electron 的标准 darwin 构建在 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 进行处理,请确保在上传之前 创建了一个记录

如果您看到类似“private APIs uses”的错误,您应该检查应用是否使用了 Electron 的 MAS 构建。

提交审核

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

MAS 构建的限制

为了满足应用沙盒的所有要求,以下模块在 MAS 构建中已被禁用:

  • crashReporter
  • autoUpdater

以下行为已更改:

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

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

其他权限

在 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 使用以下加密算法: