在提交我的日记应用 Lanternly 1.1 版本之前,我在 39 份 App Store 描述的末尾都贴上了同一个四行区块,iOS 和 macOS 都有。这个区块很无聊:一条分隔线,许可协议,隐私政策,使用条款。但如果没有它,订阅类应用就有可能被打回来,理由写着 3.1.2,哪怕订阅本身、付费墙和 StoreKit 都做得没问题。
下面讲清楚这个要求到底出自哪里,为什么 App Store Connect 给隐私政策留了字段、却没给使用条款留,以及我最后用的是什么文本。Apple 的原文一字未改,核对日期为 2026 年 10 月 13 日。
Apple 在哪里提出这个要求#
有意思的是,3.1.2 这条规则的正文里既没有提到链接,也没有出现 EULA 这个词。3.1.2(c) 要求清楚说明用户付钱能得到什么,并引用了开发者计划许可协议的 Schedule 2。真正的要求分布在另外三个地方。
Schedule 2 第 3.8(b) 节。 这里列出了自动续期订阅需要“清晰且醒目”展示的内容:名称、时长、价格。另有单独一行:
Links to Your Privacy Policy and Terms of Use must be accessible within Your Licensed Application.
这一条针对的是应用本身。
Auto-renewable subscriptions 页面补充了元数据方面的要求:
Please note that your app and App Store metadata must include links to your Terms of Use and Privacy Policy.
规则 5.1.1(i) 讲的是隐私政策,适用于所有应用,不只是订阅类:
All apps must include a link to their privacy policy in the App Store Connect metadata field and within the app in an easily accessible manner.
总结下来是两个链接,每个都要出现在两个地方:应用内和商店页面。
为什么使用条款没有自己的字段#
隐私政策很简单。“App 信息”里有 Privacy Policy URL 字段,iOS 和 macOS 都必填,而且每个语言要分别填写。
App Store Connect 里没有“Terms of Use URL”字段。有的是 License Agreement 字段,文档对它的描述如下:
Apple provides a standard EULA (End-User License Agreement) that applies in all regions. You may provide a custom license agreement that supersedes the Apple EULA for one or more regions.
于是有两条路:
| 方案 | 做法 | 适用情况 |
|---|---|---|
| 在 License Agreement 字段填自己的 EULA | 粘贴完整的条款文本,它会取代标准 EULA | 有律师,且所有地区使用统一条款 |
| 标准 EULA + 描述中的链接 | 不动这个字段,把链接放在 Description 末尾 | 几乎所有独立开发者的应用 |
我选了第二条。Lanternly 有自己的条款,但它们描述的是订阅和应用服务,而软件本身的使用许可,Apple 的标准 EULA 已经覆盖得很好。
现成的区块#
这是 Lanternly 每份描述末尾的内容。分隔线上方是正常的描述正文,下方只有链接:
_____________________
LICENSED APPLICATION END USER LICENSE AGREEMENT - https://www.apple.com/legal/macapps/stdeula/
Privacy Policy - https://dodecaidr.pro/en/projects/lanternly/privacy-policy/
Terms and Conditions - https://dodecaidr.pro/en/projects/lanternly/terms-of-service/这个区块里藏着几个决定。
所有语言里,每行的标题都用英文。 只有文档地址会变,标题保持不变。审核应用的人一眼就能认出“LICENSED APPLICATION END USER LICENSE AGREEMENT”这一行,不管描述的其余部分是什么语言。这是我自己的选择,不是 Apple 的要求。
即使没改过标准 EULA,也要放它的链接。 没有这一行,元数据里有隐私政策和我自己的条款,却没有真正生效的那份许可协议。我把三份文档都列出来,审核员就不用去猜。
链接是裸链接、完整地址、带协议头。 App Store 的描述是纯文本,不支持 HTML。不带 https:// 的地址可能不会变成可点击的链接。
所有链接都不需要登录、没有重定向就能打开。 这一点我吃过亏。Mac 版曾因规则 1.5 被拒,因为 Support URL 经过一次重定向跳到社交网络,审核员那边打不开。所以提交前,商店页面里的每个地址都值得用 curl -sIL 跑一遍,确认重定向链的最后是 200,而不是登录页。
这个区块占 4000 个字符中的 280 个。在法语描述里这一点变得很重要:正文超长了。我删掉了描述中间的“Privacy policy / Terms of use”两行,它们和区块重复,法语版最终压到了 3917 个字符。
区块上方:关于订阅的一段话#
链接解决的是文档问题。但 3.8(b) 还要求展示订阅本身的条款。价格我不写进描述:每个国家的价格都不一样,付费墙会以买家的货币显示。其余内容我写成一段:
Lanternly+ is a monthly, six-month or yearly subscription with a 7-day free trial.
Payment is charged to your Apple account at confirmation of purchase.
The subscription renews automatically unless cancelled at least 24 hours
before the end of the current period. Manage or cancel it in your Apple account settings.在描述里,一周免费试用是作为订阅的一个属性来写的。而在应用里,只有当用户仍有资格享受试用期(isEligibleForIntroOffer)时,才会出现关于这一周的说法,否则就是一个商店无法兑现的承诺。
应用内的同样链接#
要求的另一半在代码里。Lanternly 的付费墙上,购买按钮下方有一行“恢复 · 条款 · 政策”。用 SwiftUI 和 StoreKit 2 写的最小可用版本:
import SwiftUI
import StoreKit
enum LegalLinks {
// 文档语言取应用界面语言,而不是设备所在地区
private static var lang: String {
(Bundle.main.preferredLocalizations.first ?? "en").hasPrefix("ru") ? "ru" : "en"
}
static var privacy: URL { URL(string: "https://example.com/\(lang)/privacy-policy/")! }
static var terms: URL { URL(string: "https://example.com/\(lang)/terms-of-service/")! }
}
struct PaywallLegalRow: View {
var body: some View {
HStack(spacing: 6) {
Button("Restore") { Task { try? await AppStore.sync() } }
Text("·")
Link("Terms", destination: LegalLinks.terms)
Text("·")
Link("Privacy", destination: LegalLinks.privacy)
}
.font(.footnote)
.foregroundStyle(.secondary)
.lineLimit(1)
}
}注意这里用的是 preferredLocalizations。设备地区在这里不是好的依据:一个住在德国、界面用俄语的人,地区是德国。而界面语言正是他刚刚阅读付费墙所用的语言。“恢复”按钮放在同一行,理由和链接一样:Apple 要求订阅购买界面上必须有它。
如果语言很多#
Lanternly 的界面有两种语言,而商店页面有 39 种。网站上的文档有五种语言:英语、俄语、西班牙语、日语和中文。最后的规则是:如果有对应语言的文档,就链接到该语言版本。西班牙语各地区链接到 /es/,日语链接到 /ja/,两种中文都链接到 /zh-CN/,其余全部链接到 /en/。
“App 信息”里的 Privacy Policy URL 字段也需要本地化。文档说它对 iOS 和 macOS 都是必填的,所以新增语言时很容易忘掉它:它在另一个区域,不在描述旁边。
Apple 没有说清楚的地方#
- 使用条款的链接具体应该放在哪个元数据字段。 订阅页面只说了“App Store metadata”,没有指明字段。描述是最直接的选择,但从字面上看,在 License Agreement 里放自己的文本也符合要求。
- 是否每个语言都需要这个区块。 哪里都没写。我在所有语言里都放了:审核员可能用任何一种语言打开商店页面,而 280 个字符的代价不大。
- 用标准 EULA 代替自己的条款是否足够。 对很多应用来说,大概是够的。但如果订阅提供的是一项有自己规则的服务,就需要自己的条款,而且最好和律师一起撰写。
提交前的简短清单:所有语言都填好了 Privacy Policy URL,描述末尾有包含三个链接的区块,所有地址无需登录就返回 200,付费墙上有“恢复”“条款”和“政策”。这 39 份商店页面的其余字段我是怎么翻译和检查的,写在下一篇文章里。



