跳转到主内容

Mac App Store 应用程序提交指南

本指南提供以下相关资讯:

  • 如何在 macOS 上为 Electron 应用签名;
  • 如何在 Mac App Store (MAS) 上提交 Electron 应用;
  • 对于 MAS 构建版本的局限性。

要求

要为 Electron 应用签名,则必须首先安装下列应用:

您还必须注册一个苹果开发者帐户,并加入 苹果开发者计划

为 Electron 应用签名

Electron应用可以通过 Mac 应用商店或其外部进行发布。 每种方式都需要不同的签名和测试方法。 This guide focuses on distribution via Mac App Store.

以下步骤描述了如何从 Apple 获得证书,如何对Electron应用程序进行签名以及如何测试它们。

获取证书

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

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

“Apple Development”证书用于在Apple Developer网站上注册的计算机上签署用于开发和测试的应用程序。 注册方法会在准备配置文件中描述。

带有"Apple Development"证书签名的应用无法提交到Mac 应用商店。 为此,应用程序必须使用"Apple Distribution"证书进行签名。 但请注意,使用"Apple Distribution"证书签名的应用程序不能直接运行,它们必须由 Apple 重新签名才能运行,也就是只有从 Mac 应用商店下载后才能运行。

其它证书

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

"Developer ID Application"证书用于将应用发布到Mac 应用商店以外的地方之前签名。

"Deceloper ID Installer"和"Mac Installer Distribution"证书用于签署 Mac 安装程序包,而不是应用程序本身。 大多数Electron应用不使用Mac Installer Package,因此通常不需要它们。

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

Apps signed with "Apple Development" and "Apple Distribution" certificates can only run under App Sandbox, so they must use the MAS build of Electron. 然而,“Developer ID Application”证书没有这个限制,因此,用其签名的应用既可以使用普通构建也可以使用 Electron 的 MAS 构建。

传统证书名称

Apple在过去几年中一直在更改证书的名称,您可能会在阅读旧文档时遇到这些证书,并且一些工具仍然在使用旧名称。

  • “Apple Distribution”证书也叫做“3rd Party Mac Developer Application”和“Mac App Distribution”。
  • “Apple Development”证书也叫做“Mac Developer”和“Development”。

准备配置配置文件

如果您想在将应用提交给Mac App Store之前在本地机器上测试您的应用, 您必须使用"Apple Development"证书签名该应用,并在程序包中嵌入配置文件。

创建一个配置文件,您可以按照以下步骤:

  1. Apple Developer 网站上打开"证书、标识符 & 配置文件"页面。
  2. 在“标识符”页面为您的应用添加一个新的App ID。
  3. 在"设备"页面中注册本地计算机。 您可以在"系统信息"应用的"硬件"页面中找到机器的"设备 ID"。
  4. 在“Profiles”页面注册一个新的配置文件,然后下载到 /path/to/yourapp.provisionfile

启用Apple的应用沙箱

Apps submitted to the Mac App Store must run under Apple's App Sandbox, and only the MAS build of Electron can run with the App Sandbox. 在 App Sandbox 下运行时,Electron 的标准 darwin 构建将无法启动。

When signing the app with @electron/osx-sign, it will automatically add the necessary entitlements to your app's entitlements.

Extra steps without 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 开发者帐户的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 开发者团队ID:

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

使用 @electron/osx-sign 时,将通过从证书名称中提取团队 ID 来自动添加 ElectronTeamID 密钥。 如果@electron/osx-sign找不到正确的团队 ID,则可能需要你手动添加此键 。

签署应用程序以进行开发

要对可以在您的开发机器上运行的应用程序进行签名,您必须使用“Apple Development”证书对其进行签名,并将配置文件传递给 @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 的情况下进行签名,则必须将配置文件放入 YourApp.app/Contents/embedded.provisionprofile

签名的应用程序只能在通过配置文件注册的机器上运行,这是在提交到 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'
})

Submit apps to the Mac App Store

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

However, this guide do not ensure your app will be approved by Apple; you still need to read Apple's Submitting Your App guide on how to meet the Mac App Store requirements.

上传

Apple Transporter should be used to upload the signed app to App Store Connect for processing, making sure you have created a record before uploading.

如果您看到类似私有 API 使用的错误,您应该检查应用程序是否使用了 Electron 的 MAS 构建。

提交审核

After uploading, you should submit your app for review.

MAS 构建限制

为了让你的应用满足沙箱的所有条件,在 MAS 构建的时候,下面的模块已被禁用:

  • crashReporter
  • autoUpdater

并且下面的行为也改变了:

  • 一些视频采集功能无效。
  • 某些辅助功能无法访问。
  • 应用无法检测 DNS 变化。

Also, due to the usage of app sandboxing, the resources which can be accessed by the app are strictly limited; you can read App Sandboxing for more information.

附加授权

Every app running under the App Sandbox will run under a limited set of permissions, which limits potential damage from malicious code. 根据您的应用使用的 Electron API,您可能需要在应用的权限文件中添加额外的权限。 否则,App Sandbox 可能会阻止您使用它们。

Entitlements are specified using a file with format like property list (.plist) or XML. You must provide an entitlement file for the application bundle itself and a child entitlement file which basically describes an inheritance of properties, specified for all other enclosing executable files like binaries, frameworks (.framework), and dynamically linked libraries (.dylib).

A full list of entitlements is available in the App Sandbox documentation, but below are a few entitlements you might need for your MAS app.

With @electron/osx-sign, you can set custom entitlements per file as such:

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/>

启用传入的网络连接,让你的应用程序打开网络 socket 监听:

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

See the Enabling Network Access documentation for more details.

dialog.showOpenDialog

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

See the Enabling User-Selected File Access documentation for more details.

dialog.showSaveDialog

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

See the Enabling User-Selected File Access documentation for more details.

Electron 使用的加密算法

根据你发布应用所在的国家或地区,你可能需要提供您软件使用的加密算法的信息。 See the encryption export compliance docs for more information.

Electron 使用下列加密算法: