Skip to main content

Mac App Store 提交指南

¥Mac App Store Submission Guide

本指南提供以下信息:

¥This guide provides information on:

  • 如何在 macOS 上签署 Electron 应用;

    ¥How to sign Electron apps on macOS;

  • 如何将 Electron 应用提交到 Mac App Store (MAS);

    ¥How to submit Electron apps to Mac App Store (MAS);

  • MAS 构建的局限性。

    ¥The limitations of the MAS build.

要求

¥Requirements

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

¥To sign Electron apps, the following tools must be installed first:

你还必须注册一个 Apple 开发者账户并加入 苹果开发者计划

¥You also have to register an Apple Developer account and join the Apple Developer Program.

签署 Electron 应用

¥Sign Electron apps

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

¥Electron apps can be distributed through Mac App Store or outside it. Each way requires different ways of signing and testing. This guide focuses on distribution via Mac App Store.

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

¥The following steps describe how to get the certificates from Apple, how to sign Electron apps, and how to test them.

获得证书

¥Get certificates

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

¥The simplest way to get signing certificates is to use Xcode:

  1. 打开 Xcode 并打开 "账户" 首选项;

    ¥Open Xcode and open "Accounts" preferences;

  2. 使用你的 Apple 账户登录;

    ¥Sign in with your Apple account;

  3. 选择队伍,点击 "管理证书";

    ¥Select a team and click "Manage Certificates";

  4. 在签名证书表的左下角,单击“添加”按钮 (+),然后添加以下证书:

    ¥In the lower-left corner of the signing certificates sheet, click the Add button (+), and add following certificates:

    • "苹果开发"

      ¥"Apple Development"

    • "苹果分销"

      ¥"Apple Distribution"

"苹果开发" 证书用于在已在 Apple Developer 网站上注册的计算机上对用于开发和测试的应用进行签名。注册方法将在 准备配置文件 中描述。

¥The "Apple Development" certificate is used to sign apps for development and testing, on machines that have been registered on Apple Developer website. The method of registration will be described in Prepare provisioning profile.

使用 "苹果开发" 证书签名的应用无法提交到 Mac App Store。为此,应用必须使用 "苹果分销" 证书进行签名。但需要注意的是,使用 "苹果分销" 证书签名的应用不能直接运行,必须经过 Apple 重新签名才能运行,只有从 Mac App Store 下载后才能运行。

¥Apps signed with the "Apple Development" certificate cannot be submitted to Mac App Store. For that purpose, apps must be signed with the "Apple Distribution" certificate instead. But note that apps signed with the "Apple Distribution" certificate cannot run directly, they must be re-signed by Apple to be able to run, which will only be possible after being downloaded from the Mac App Store.

其他证书

¥Other certificates

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

¥You may notice that there are also other kinds of certificates.

"开发者 ID 应用" 证书用于在将应用分发到 Mac App Store 之外之前对应用进行签名。

¥The "Developer ID Application" certificate is used to sign apps before distributing them outside the Mac App Store.

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

¥The "Developer ID Installer" and "Mac Installer Distribution" certificates are used to sign the Mac Installer Package instead of the app itself. Most Electron apps do not use Mac Installer Package so they are generally not needed.

证书类型的完整列表可以在 此处 中找到。

¥The full list of certificate types can be found here.

使用 "苹果开发" 和 "苹果分销" 证书签名的应用只能在 应用沙箱 下运行,因此它们必须使用 Electron 的 MAS 版本。但是,"开发者 ID 应用" 证书没有此限制,因此用它签名的应用可以使用 Electron 的正常构建或 MAS 构建。

¥Apps signed with "Apple Development" and "Apple Distribution" certificates can only run under App Sandbox, so they must use the MAS build of Electron. However, the "Developer ID Application" certificate does not have this restrictions, so apps signed with it can use either the normal build or the MAS build of Electron.

旧证书名称

¥Legacy certificate names

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

¥Apple has been changing the names of certificates during past years, you might encounter them when reading old documentations, and some utilities are still using one of the old names.

  • "苹果分销" 证书也被命名为 "3rd 方 Mac 开发者应用" 和 "Mac 应用分发"。

    ¥The "Apple Distribution" certificate was also named as "3rd Party Mac Developer Application" and "Mac App Distribution".

  • "苹果开发" 证书也被命名为 "Mac 开发者" 和 "开发"。

    ¥The "Apple Development" certificate was also named as "Mac Developer" and "Development".

准备配置文件

¥Prepare provisioning profile

如果你想在将应用提交到 Mac App Store 之前在本地计算机上测试你的应用,则必须使用 "苹果开发" 证书以及嵌入在应用包中的配置文件来签署应用。

¥If you want to test your app on your local machine before submitting your app to the Mac App Store, you have to sign the app with the "Apple Development" certificate with the provisioning profile embedded in the app bundle.

对于 创建配置文件,你可以按照以下步骤操作:

¥To create a provisioning profile, you can follow the below steps:

  1. 打开 苹果开发者 网站上的 "证书、标识符和配置文件" 页面。

    ¥Open the "Certificates, Identifiers & Profiles" page on the Apple Developer website.

  2. 在 "身份标识" 页面中为你的应用添加新的应用 ID。

    ¥Add a new App ID for your app in the "Identifiers" page.

  3. 在 "设备" 页面注册你的本地机器。你可以在 "系统信息" 应用的 "硬件" 页面中找到你机器的 "设备 ID"。

    ¥Register your local machine in the "Devices" page. You can find your machine's "Device ID" in the "Hardware" page of the "System Information" app.

  4. 在 "型材" 页面注册一个新的 Provisioning Profile,并将其下载到 /path/to/yourapp.provisionprofile

    ¥Register a new Provisioning Profile in the "Profiles" page, and download it to /path/to/yourapp.provisionprofile.

启用 Apple 的应用沙箱

¥Enable Apple's App Sandbox

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

¥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. The standard darwin build of Electron will fail to launch when run under App Sandbox.

使用 @electron/osx-sign 签署应用时,它会自动将必要的权利添加到应用的权利中。

¥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 的情况下对应用进行签名,则必须确保应用包的权利至少具有以下密钥:

¥If you are signing your app without using @electron/osx-sign, you must ensure the app bundle's entitlements have at least following keys:

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 开发者账户的团队 ID,your.bundle.id 应替换为应用的 App ID。

¥The TEAM_ID should be replaced with your Apple Developer account's Team ID, and the your.bundle.id should be replaced with the App ID of the app.

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

¥And the following entitlements must be added to the binaries and helpers in the app's bundle:

<?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:

¥And the app bundle's Info.plist must include ElectronTeamID key, which has your Apple Developer account's Team ID as its value:

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

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

¥When using @electron/osx-sign the ElectronTeamID key will be added automatically by extracting the Team ID from the certificate's name. You may need to manually add this key if @electron/osx-sign could not find the correct Team ID.

签署应用以进行开发

¥Sign apps for development

要签署可在你的开发计算机上运行的应用,你必须使用 "苹果开发" 证书对其进行签名,并将配置文件传递给 @electron/osx-sign

¥To sign an app that can run on your development machine, you must sign it with the "Apple Development" certificate and pass the provisioning profile to @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

¥If you are signing without @electron/osx-sign, you must place the provisioning profile to YourApp.app/Contents/embedded.provisionprofile.

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

¥The signed app can only run on the machines that registered by the provisioning profile, and this is the only way to test the signed app before submitting to Mac App Store.

签署应用以提交到 Mac App Store

¥Sign apps for submitting to the Mac App Store

要对将提交到 Mac App Store 的应用进行签名,你必须使用 "苹果分销" 证书对其进行签名。请注意,使用此证书签名的应用将无法在任何地方运行,除非是从 Mac App Store 下载的。

¥To sign an app that will be submitted to Mac App Store, you must sign it with the "Apple Distribution" certificate. Note that apps signed with this certificate will not run anywhere, unless it is downloaded from Mac App Store.

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

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

将应用提交到 Mac App Store

¥Submit apps to the Mac App Store

使用 "苹果分销" 证书对应用进行签名后,你可以继续将其提交到 Mac App Store。

¥After signing the app with the "Apple Distribution" certificate, you can continue to submit it to Mac App Store.

但是,本指南并不能确保你的应用将获得 Apple 的批准;你仍然需要阅读 Apple 的 提交你的应用 指南,了解如何满足 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.

上传

¥Upload

苹果运输车 应该用于将签名的应用上传到 App Store Connect 进行处理,在上传之前确保你有 创造了一个记录

¥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 版本。

¥If you are seeing errors like private APIs uses, you should check if the app is using the MAS build of Electron.

提交审核

¥Submit for review

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

¥After uploading, you should submit your app for review.

MAS 构建的局限性

¥Limitations of MAS Build

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

¥In order to satisfy all requirements for app sandboxing, the following modules have been disabled in the MAS build:

  • crashReporter

  • autoUpdater

并且以下行为已更改:

¥and the following behaviors have been changed:

  • 视频捕获可能不适用于某些机器。

    ¥Video capture may not work for some machines.

  • 某些辅助功能可能无法使用。

    ¥Certain accessibility features may not work.

  • 应用不会意识到 DNS 更改。

    ¥Apps will not be aware of DNS changes.

另外,由于应用沙箱的使用,应用可以访问的资源受到严格限制;你可以阅读 应用沙箱 了解更多信息。

¥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.

额外权利

¥Additional entitlements

在 App Sandbox 下运行的每个应用都将在一组有限的权限下运行,这限制了恶意代码的潜在损害。根据你的应用使用的 Electron API,你可能需要向应用的权利文件添加额外的权利。否则,应用沙箱可能会阻止你使用它们。

¥Every app running under the App Sandbox will run under a limited set of permissions, which limits potential damage from malicious code. Depending on which Electron APIs your app uses, you may need to add additional entitlements to your app's entitlements file. Otherwise, the App Sandbox may prevent you from using them.

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

¥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).

应用沙箱 文档中提供了完整的授权列表,但以下是你的 MAS 应用可能需要的一些授权。

¥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.

使用 @electron/osx-sign,你可以为每个文件设置自定义权利,如下所示:

¥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)
})
})

网络接入

¥Network access

启用传出网络连接以允许你的应用连接到服务器:

¥Enable outgoing network connections to allow your app to connect to a server:

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

启用传入网络连接以允许你的应用打开网络监听套接字:

¥Enable incoming network connections to allow your app to open a network listening 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 使用的密码算法

¥Cryptographic Algorithms Used by Electron

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

¥Depending on the countries in which you are releasing your app, you may be required to provide information on the cryptographic algorithms used in your software. See the encryption export compliance docs for more information.

Electron 使用以下加密算法:

¥Electron uses following cryptographic algorithms: