App 快上架了,调研后发现隐私政策需要是 URL 形式才可以通过政策审核。
这是大多数独立开发者都经历过的时刻。App Store Connect 那个输入框就在那里,空着,像一道必须跨过去的门槛。你知道要填,但不知道填什么、怎么弄、放在哪里。
这篇文章是我给自己 iOS 应用「鲸海语记」搭建隐私政策页面的完整过程,从法律要求到代码,从部署到 DNS,踩了不少坑,一次说清楚。
先搞清楚:为什么隐私政策 URL 是刚需
很多独立开发者的第一反应是:「我就一个小 App,用户又没几个,写进 App 里不行吗?」
不行。
Apple 强制要求 在 App Store Connect 填写隐私政策 URL,这是上架审核的必检项。缺了直接打回。
更严格的是国内法律层面。《个人信息保护法》(PIPL)第 14 条明确规定:基于同意处理个人信息,必须是用户在充分知情下自愿、明确作出,禁止默认勾选。
翻译成产品语言就是:
- • 首次启动必须弹窗,全屏覆盖,不可跳过
- • 弹窗里必须有隐私政策的 HTTPS 链接,可直接点开
- • 按钮只能是「同意」和「拒绝」,不能用「我知道了」「下一步」之类的模糊表述
- • 用户点同意之前,任何 SDK 不能初始化,任何网络请求不能发出
最后这一条是很多开发者没意识到的红线。你的统计 SDK、推送 SDK,如果在用户同意之前就跑起来了,审核照样打回,甚至面临下架风险。
对于「鲸海语记」这种涉及语音转文字的 App,审核更严。语音数据属于敏感个人信息,需要在弹窗里单独提示,在隐私政策里明确说明目的、处理方式和保存期限。
iOS 端最简实现
逻辑并不复杂:
if !UserDefaults.standard.bool(forKey: "PrivacyAgreed") { let privacyVC = PrivacyPolicyViewController() privacyVC.onAgree = { UserDefaults.standard.set(true, forKey: "PrivacyAgreed") self.initializeSDKs() // 同意后再初始化 SDK self.enterMainInterface() } privacyVC.onReject = { exit(0) // 拒绝则退出 App } window.rootViewController = privacyVC} else { enterMainInterface()}
关键点:SDK 初始化放在 onAgree 回调里,不是 App 启动时。
隐私政策 URL 放哪里
搞清楚法律要求之后,下一个问题是:这个 URL 怎么来?
「鲸海语记」后端只有 Supabase,没有专门的服务器,但有个域名 jinghai.ink。
方案对比:
| 方案 | 成本 | 难度 | SSL | 推荐度 |
|---|---|---|---|---|
| GitHub Pages(公开仓库) | 免费 | 低 | 自动 | 推荐 |
| Cloudflare Pages 直接上传 | 免费 | 低 | 自动 | 推荐 |
| Supabase Storage | 免费 | 低 | 自动 | 可用但 URL 丑 |
| 自建服务器 | 有成本 | 高 | 手动 | 不必要 |
我的项目仓库是私有的,GitHub Pages 免费版不支持私有仓库开启 Pages。所以选了 Cloudflare Pages 直接上传。
隐私政策写什么
先把内容搞定,再谈部署。
「鲸海语记」的情况:
- • 第三方服务:Supabase、腾讯云 ASR、硅基流动实时语音 API、Groq ASR API
- • 数据上传规则:Pro 会员语音数据上传至 Supabase(新加坡节点),普通用户全程本地处理
- • 无账号系统:不收集姓名、手机号、邮箱等身份信息
这几条是隐私政策的核心差异点,必须写清楚。
隐私政策的结构:
-
- 概述(开发者主体、适用范围)
-
- 收集哪些信息(按用户类型分开说明)
-
- 第三方 SDK 列表(服务名、提供方、用途、各自的隐私政策链接)
-
- 数据用途
-
- 数据存储与安全(数据中心位置、传输加密方式)
-
- 用户权利(访问、删除、撤回同意、数据可携带)
-
- 未成年人保护
-
- 政策更新说明
-
- 联系方式
建议做成中英双语单页,用 JavaScript 根据浏览器语言自动切换,一个 URL 搞定两种语言:
var userLang = navigator.language || navigator.userLanguage || 'zh';if (userLang.startsWith('zh')) { setLang('zh');} else { setLang('en');}
英文环境打开显示英文,中文环境显示中文,App 内中英文版本都指向同一个链接。
Cloudflare Pages 部署踩坑记录
部署过程踩了几个坑,记录下来。
坑一:Pages 不支持直接上传单个文件
Cloudflare Pages 的 Direct Upload 只接受文件夹或压缩包,不能拖单个 HTML 文件进去。
解决方法:新建一个文件夹,把 HTML 放进去,上传整个文件夹。
坑二:第一次创建的是 Worker 不是 Pages
Workers 需要写 JavaScript 代码才能响应请求,不是静态文件托管。两者的创建入口不一样:
- • Workers:
Workers 和 Pages→创建→Worker - • Pages:
Workers 和 Pages→创建→Pages→直接上传
创建成功后访问地址格式是 xxx.pages.dev,加上文件路径即可访问:
https://speechnote-legal.pages.dev/privacy-policy.html
坑三:多个 App 用同一个项目
隐私政策是 App 专属的,不同 App 内容不同,不能共用同一个 URL。
正确的做法是在项目里按 App 建子目录:
speechnote-legal/ speechnote/ privacy-policy.html app2/ privacy-policy.html
最终 URL 结构:
privacy.jinghai.ink/speechnote/privacy-policy.htmlprivacy.jinghai.ink/app2/privacy-policy.html
自定义域名与 SSL 的弯路
Pages 部署完成后,想绑定 privacy.jinghai.ink,走了一段弯路。
第一步:在阿里云 DNS 加了一条 CNAME 记录,指向 speechnote-legal.pages.dev。
然后在 Cloudflare Pages 的自定义域设置里填入 privacy.jinghai.ink。
访问的时候报错:
ERR_SSL_VERSION_OR_CIPHER_MISMATCH
原因:DNS 在阿里云,Cloudflare Pages 无法自动为这个域名签发证书。SSL 证书的签发需要域名解析权在 Cloudflare 手里。
根本解决方案:把域名 NS 迁移到 Cloudflare。
流程:
-
- Cloudflare Dashboard → 添加站点 → 填
jinghai.ink→ 免费计划
- Cloudflare Dashboard → 添加站点 → 填
-
- Cloudflare 自动扫描现有 DNS 记录(没有记录就手动添加 CNAME)
-
- 记下 Cloudflare 给的两个 NS 地址,类似:
emma.ns.cloudflare.comgordon.ns.cloudflare.com
-
- 去阿里云域名控制台 → DNS 修改 → 替换为上面两个 NS
-
- 等 1-24 小时,收到 Cloudflare 激活邮件
迁移完成后,privacy.jinghai.ink 的 HTTPS 自动生效,证书由 Cloudflare 统一签发管理,以后不用操心。
为什么网友叫 Cloudflare「活菩萨」
Cloudflare 成立于 2009 年,总部美国,全球超过 300 个数据中心节点,是世界上最大的网络基础设施提供商之一,客户包括无数财富 500 强企业。
但它在独立开发者圈子里被叫做「活菩萨」,原因很简单:免费套餐给得太狠了。
| 服务 | 正常价值 | Cloudflare 免费额度 |
|---|---|---|
| SSL 证书 | 数百元/年 | 无限,自动签发 |
| CDN 加速 | 按流量收费 | 免费,全球 300+ 节点 |
| DDoS 防护 | 企业级服务 | 免费基础防护 |
| DNS 解析 | 付费服务 | 免费,全球最快之一 |
| Cloudflare Pages | 静态托管收费 | 免费,无限站点 |
| Cloudflare Workers | 边缘计算收费 | 每天 10 万次请求免费 |
| Cloudflare Tunnel | 内网穿透收费 | 免费 |
对独立开发者来说,一分钱不花,套上 Cloudflare,就拥有了大厂级别的网络基础设施。小站被 DDoS 攻击?开 Cloudflare 代理,流量直接扛住。SSL 过期?Cloudflare 自动续签,永远不用管。
这种慷慨在行业里属于异类。
当然 Cloudflare 不是真菩萨,它的商业逻辑很清晰:用免费服务吸引海量用户,等用户的业务成长起来,自然会升级到付费计划。免费套餐是最好的用户教育和产品黏性。
但对还在冷启动阶段的独立开发者来说,这确实是活菩萨级别的存在。
给独立开发者的几条总结
关于合规
- • 隐私政策 URL 是 App Store 上架必填项,没有捷径
- • 国内上架额外要求首启弹窗 + 明示同意,SDK 同意前不能初始化
- • 语音、人脸等敏感数据需要在隐私政策里单独说明
关于部署
- • 没有后端服务器,用 Cloudflare Pages 直接上传 HTML,免费够用
- • 中英双语做在同一个页面,JS 自动切换,一个 URL 解决两种语言
- • 多个 App 用子目录区分,不要共用同一个隐私政策页面
关于域名
- • 域名 NS 迁移到 Cloudflare,SSL 自动管理,一劳永逸
- • 阿里云或 Spaceship 注册的域名都可以迁,操作一样,等 1-24 小时生效
做独立开发,每个细节都要自己扛。隐私政策这件事,前期花两个小时搞定,后面就不用再想了。
2026.03.1117:56 沪 · 汇金路KFC
📌 声明:本文由 AI 辅助完成