跳至主要内容

Mac App Store 提交指南

本指南提供以下信息

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

要求

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

您还必须注册 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 之前在本地机器上测试您的应用,您必须使用“Apple Development”证书签名该应用,并将 provisioning profile 嵌入到应用包中。

创建 provisioning profile,您可以按照以下步骤操作

  1. Apple Developer网站上打开“证书、标识符与描述文件”页面。
  2. 在“标识符”页面中为您的应用添加新的 App ID。
  3. 在“设备”页面中注册您的本地机器。您可以在“系统信息”应用的“硬件”页面中找到您机器的“设备 ID”。
  4. 在“描述文件”页面中注册新的 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 签名应用时,它会自动将必要的 entitlements 添加到您的应用的 entitlements 中。

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

如果您不使用 @electron/osx-sign 签名应用,必须确保应用包的 entitlements 至少包含以下键

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。

并且必须将以下 entitlements 添加到应用包中的二进制文件和辅助程序中

<?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 Sandboxing了解更多信息。

额外的 entitlements

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

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

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

使用 @electron/osx-sign,您可以按文件设置自定义 entitlements,如下所示

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