跳到正文
返回博客
·约 2 分钟读完

Mac App Store 提审检查清单

一款在本地全部测试通过的 Mac 应用,仍然可能因为只在 Mac App Store 才有的规则被拒。沙盒与用户选择的文件、不能自带更新、主窗口要能重新打开、16:10 截图、权限、图标下的名字、副标题里的“Mac”,以及 Mac 版本自己的审核信息。

Mac App Store 的审核会查一些 iPhone 审核从来不查的东西,而且这些问题在本地构建和测试里都不会暴露。它们关心的是应用通过什么渠道分发,以及 Mac 用户对一个应用的行为有什么预期。提交 Mac 版本之前,值得在真机上手动按下面的顺序过一遍。

1. 应用开了沙盒,用户的文件存到用户选的地方

Apple 文档写明:"To distribute a macOS app through the Mac App Store, you must enable the App Sandbox capability."(要通过 Mac App Store 分发,必须开启 App Sandbox。)指南 2.4.5(i) 也要求应用 "must be appropriately sandboxed"(适当地沙盒化)。

坑在于:开了沙盒以后,往“文稿”目录写文件照样成功,只是文件落进了应用自己的容器,一个用户永远不会去打开的隐藏目录。我们的一款 Mac 应用就是因此被拒,Apple 的原话是应用 "saves user data to the app's container, which is not user accessible"(把用户数据存进了用户无法访问的应用容器)。

  • 用户做出来的东西,一律通过存储对话框保存:AppKit 用 NSSavePanel,SwiftUI 用 fileExporter。
  • 在 App Sandbox 能力里把 User Selected File 设为 Read/Write(com.apple.security.files.user-selected.read-write)。
  • 容器只留给你自己的数据:数据库、缓存、设置。

细节和代码见 2.4.5:沙盒存文件与自带更新检查。

2. 每一项权限都说得出理由

权限开得过宽,同样会被 2.4.5(i) 拒。打印准备上传的归档里已签名的权限:

codesign -d --entitlements - YourApp.app

逐行读。商店版本里不能有 get-task-allow,一句话解释不清用途的都删掉。想把 .provisionprofile 读成表格,或者粘贴一个 .entitlements 文件查看,可以用我们的 描述文件查看器。

3. 不自带更新、不用安装器、不要授权码

指南 2.4.5 列出了 Mac App Store 应用不能做的事。独立开发者最常踩的几条:

  • (vii) 只能通过 Mac App Store 更新。 "Other update mechanisms are not allowed."(不允许其他更新机制。)Apple 给我们的消息里点名的是 "frameworks or APIs that may be used to update the app"(可能用于更新应用的框架或 API),所以只藏掉菜单项不够,更新框架要整个从商店版本里拿掉。
  • (vi) 启动时不弹授权协议,不要授权码, 也不要自己做拷贝保护。
  • (iii) 未经同意不在登录时自启, 用户退出后也不留后台进程。
  • (ii) 不用第三方安装器。 一个自包含的应用包,用 Xcode 构建和提交。

如果你同时卖官网下载版,给它单独一个构建配置,把更新和授权相关代码放在编译条件后面。

4. 主窗口随时能重新打开

按 ⌘W 关掉主窗口。如果应用还在运行,菜单里却没有任何一项能把窗口叫回来,那就是我们自己收到过的 Guideline 4(设计) 拒审。要么在最后一个窗口关闭时退出(先保存),要么提供一个能重新打开窗口的菜单项。SwiftUI 和 AppKit 的改法见 关掉主窗口后没法再打开。

5. 截图是 16:10

App Store Connect 要求 Mac 截图是以下四种尺寸之一,全部是 16:10:

  • 1280 × 800
  • 1440 × 900
  • 2560 × 1600
  • 2880 × 1800

直接截一个窗口,或者截一块比例不同的屏幕,都对不上。和所有 App Store 截图一样,不能带 alpha 通道或透明。用 截图尺寸工具 检查并调整尺寸。如果要加预览视频,Apple 只接受横向的 Mac 预览。

截图用一个干净的桌面:程序坞里没有别的应用,没有私人文件,用你自己的示例内容。一张 Mac 截图露出来的,远不止你的应用。

6. 图标下的名字和商店名一致

在 Mac 上,用户在访达、程序坞和应用菜单里看到的名字来自应用包,而不是 App Store Connect。Apple 文档说 CFBundleName 最多 15 个字符,并且在没有设置 CFBundleDisplayName 时系统可能显示它。指南 2.3.8 要求应用名和图标 "similar to avoid creating confusion"(保持一致,避免混淆)。

装好构建,在你售卖的每种语言下看一眼应用菜单、访达和程序坞,逐个和商店名比对。见 2.3.8:名字对不上。

7. “Mac”不能成为你应用身份的一部分

很多人想在副标题里写“for Mac”或“Mac”。我们就因为元数据里用了 Apple 的商标收到过 Guideline 5.2.5。Apple 商标使用指南写道,你 "may not use the Mac trademark standing alone except to denote or refer to the Apple Macintosh product line"(不能单独使用 Mac 商标,除非指代 Apple 的 Mac 产品线);说明兼容性时要用 "runs on""for use with""compatible with" 这类指代性短语,而且要比你自己的产品名更不显眼。Apple 的营销指南也是同样的写法:要说“应用名 for iPhone”,不要说“iPhone 应用名”。

实际做法:副标题的 30 个字符用来说应用做什么。用户在 Mac App Store 里本来就知道这是 Mac 应用。详见 元数据里的品牌名。

8. Mac 版本有自己的审核信息

Apple 帮助文档说,各平台的版本是分开提交的。如果你的应用记录里还有 iOS 版,Mac 版本有自己的截图、版权信息、构建和 App 审核信息。在 Mac 版本页上核对:

  • 版权 已填写,这是必填项。
  • 需要登录 只在应用真的有登录时才勾选,并且演示账号能用。
  • 审核备注 写清楚审核员可能找不到的东西,比如菜单栏图标,或者需要打开某种文件才能用的功能。需要的话附上示例文件。
  • 出口合规: Mac target 的 Info.plist 里同样要设置 ITSAppUsesNonExemptEncryption,否则每次上传都要重新回答。

9. 在审核员用的那类 Mac 上测试

审核员会在消息里写明他们用的设备,我们的 Mac 应用遇到的是笔记本,不是大尺寸外接显示器。按笔记本屏幕的尺寸测一遍:窗口放得下,底部没有被截掉,默认窗口大小下能正常使用。再用一个全新的用户账户启动一次,看看没有任何设置和文件时的首次运行。

一分钟自检

拿准备上传的归档:保存一样东西,确认弹出了存储对话框问你存到哪里;按 ⌘W,然后只用菜单栏把窗口找回来;打开应用菜单和设置,确认没有更新相关的项;读一遍 codesign -d --entitlements - 的输出。然后把 提审前检查清单 剩下的部分过完;万一还是被拒,看 被拒之后怎么办。更多发版工具在 工具箱页面。

以上来自 Obelisk Club 自己的送审记录。Apple 的措辞和要求会变,请以当前 App Review 指南、App Store Connect 帮助文档和 Apple 商标使用指南为准。

作者

独立开发者,在 Obelisk Club 做本地优先的 Mac 与 iOS 效率应用。 关于作者 →