# Guideline 1.2 用户生成内容：Apple 的要求

> 只要用户会发布内容，就要有过滤、举报、屏蔽、公开联系方式和用户同意的条款。附 Expo 与 Supabase 清单。

原始页面：[Guideline 1.2 用户生成内容：Apple 的要求](https://devoria.fr/zh-hans/blog/guideline-1-2-user-generated-content-apple)
作者：[Mehdi Azizi](https://devoria.fr/zh-hans/mehdi-azizi)
发布：2026-11-04
内容最后修订：2026-11-04


只要用户发布的东西会被其他人看到，guideline 1.2 就适用：一条消息、一张照片、一条评价，在我看来，排行榜里的一个昵称也算。这时 Apple 的条文要求四样东西：过滤、举报并及时处理、屏蔽，以及公开的联系方式。**拒审消息里还多了第五项要求：用户必须同意使用条款，条款明确不容忍令人反感的内容和滥用行为的用户。**

这篇指南讲的不是一次被拒的经历。我要展示的是，我的交易练习 app TradaZen 的排行榜开始显示玩家自选昵称时，我做了哪些措施。如果你想先了解拒审原因的全貌，可以看[Apple 为什么拒绝你的 app](https://devoria.fr/zh-hans/blog/apple-app-rejection-reasons-real-cases)。

## guideline 1.2 说了什么？

1.2 叫 “User-Generated Content”，位于 [App Review Guidelines](https://developer.apple.com/app-store/review/guidelines/#user-generated-content) 第 1 部分 “Safety”。它针对的是含有用户内容或社交网络服务的 app。为了防止滥用，这类 app “must include” 四项保护措施：

- “A method for filtering objectionable material from being posted to the app”：**在发布之前拦截令人反感内容的过滤机制**。
- “A mechanism to report offensive content and timely responses to concerns”：举报内容的途径，并且对举报及时响应。
- “The ability to block abusive users from the service”：可以屏蔽有滥用行为的用户。
- “Published contact information so users can easily reach you”：公开的、容易找到的联系方式。

条文的当前版本（2026 年 6 月 8 日更新）说得更进一步。它强调，删除违反规则、你的使用条款或社区规范的内容是你的责任。如果 Apple 发现这类内容，会要求你删除并提交改进计划，在此期间还可能下架 app。

条文还列出了不适合上架 App Store 的 app：主要用于色情、类似 Chatroulette 的随机或匿名聊天、给真人外貌打分、威胁或骚扰的 app。**对于这些用途，四项保护措施也不够。** 1.2.1 则为创作者类 app 增加了规则，特别是对超出 app 年龄分级的内容进行年龄验证。

## 你的 app 受影响吗？

App Store Connect 的年龄分级问卷给出了一个很好的定义。当用户创建的内容在 app 内广泛传播时，比如视频、照片、文字或音频，它就称之为[用户生成内容](https://developer.apple.com/help/app-store-connect/reference/app-information/age-ratings-values-and-definitions)。用户之间的消息功能则单独列出。

| 其他人能看到的内容 | 受影响吗？     |
| ------------------ | -------------- |
| 成员之间的消息     | 是             |
| 公开的照片或评价   | 是             |
| 排行榜里的昵称     | 是，我这么认为 |
| 私人笔记           | 否             |
| 你自己写的内容     | 否             |

Apple 没有提到昵称。但我还是把昵称当作用户内容处理：任何人都可以起一个侮辱性的昵称，而其他玩家能看到它。这是我为 TradaZen 排行榜做的选择。

## 需要实现的 5 个机制（Expo 和 Supabase）

2025 年底，一位开发者在 [Apple 论坛](https://developer.apple.com/forums/thread/807358)上公开了他收到的 1.2 拒审消息，里面列出了 Apple 期望的措施。开头是 “Require that users agree to terms (EULA)”，结尾是一个时限要求：在 “within 24 hours” 内处理举报，删除内容并封禁发布者。

| 机制         | 在哪里实现            |
| ------------ | --------------------- |
| 同意使用条款 | 页面和用户资料        |
| 过滤         | 服务器，在显示之前    |
| 举报         | 按钮和数据表          |
| 屏蔽         | 数据表和访问规则      |
| 公开联系方式 | App 和 App Store 页面 |

下面的 SQL 示例需要根据你的数据结构调整。它们基于 [Supabase 的行级访问规则](https://supabase.com/docs/guides/database/postgres/row-level-security)，即使有人绕过你的 app，这些规则依然生效。

### 1. 用户同意的使用条款，对滥用零容忍

你的使用条款必须白纸黑字写明：不容忍任何令人反感的内容和滥用行为的用户。条款示例（请找人审阅，这不是法律意见）：“不容忍任何冒犯、仇恨、色情或骚扰内容。被举报的内容可能被删除，发布者可能被封禁，恕不另行通知。”

**注册按钮下面一句被动的说明证明不了用户同意：要让用户做出明确的操作。** 在第一次发布之前，放一个页面，带上使用条款的链接和一个“我同意”按钮。把同意的日期和版本记录在用户资料里，缺少这两项就禁止发布：

```sql
create policy "publier après les CGU" on public.posts
for insert to authenticated
with check (
  auth.uid() = author_id
  and exists (
    select 1 from public.profiles p
    where p.id = auth.uid() and p.cgu_acceptees_le is not null
  )
);
```

### 2. 在其他人看到之前进行过滤

过滤放在服务器上，因为 app 的代码可以被绕过。app 里的副本只是为了立刻提醒用户。

在 TradaZen 里，数据库里的一个函数会检查每个昵称，app 也用同一份词表来提醒玩家。我会让两边保持一致。在服务器端，冒犯性的昵称在写入时不会被拒绝：**而是在显示时替换成一个中性昵称，这样就不会因为误判把人挡在外面**。

误判来得很快。在 TradaZen 里，过滤器的第一个版本会屏蔽 Dominique、Monique 或 Véronique 这样的名字，因为它们包含了一个粗话的片段。解决办法：匹配完整的词，而不是词的片段。另外，app 在日语和中文市场上架，所以过滤器也覆盖这两种语言。

### 3. 举报，24 小时内处理

每条发布的内容都带一个“举报”按钮。在 TradaZen 里，联赛排行榜中被举报的昵称会立刻在举报者的手机上显示为一个中性标签。随后举报会发送到服务器，如果手机离线，稍后会重新发送。

数据库这边，建一张举报表，每个人对每条内容只能举报一次：

```sql
create table public.reports (
  id uuid primary key default gen_random_uuid(),
  reporter_id uuid not null references auth.users (id) on delete cascade,
  target_id uuid not null,
  reason text,
  created_at timestamptz not null default now(),
  unique (reporter_id, target_id)
);
alter table public.reports enable row level security;
create policy "mes signalements" on public.reports
for insert to authenticated
with check (auth.uid() = reporter_id);
```

在 TradaZen 里，**被多名玩家举报的昵称会被替换成中性昵称**，而且被举报的人永远看不到举报记录。一个通用的注意事项：用于举报的标识符不能让内容作者修改，否则他可以躲过隐藏。

自动隐藏不能代替你的决定。为了做到 24 小时内处理，每次有举报都要让自己收到通知：[Supabase 数据库 webhook](https://supabase.com/docs/guides/database/webhooks) 可以调用一个服务器函数给你发消息。用来删除内容的密钥要留在服务器上，我在 [Expo app 中的 API 密钥](https://devoria.fr/zh-hans/blog/expo-api-secret-key-security)里解释过。

### 4. 立即生效的屏蔽

建一张屏蔽表，再加一条访问规则，把被屏蔽者的内容从屏蔽者的信息流里去掉：

```sql
create policy "sans les bloqués" on public.posts
for select to authenticated
using (
  not exists (
    select 1 from public.blocks b
    where b.blocker_id = auth.uid() and b.blocked_id = posts.author_id
  )
);
```

在 TradaZen 里，通过一个代码添加好友，也可以移除并屏蔽好友。**被屏蔽的好友会从列表中消失，即使他再次发送请求也一样。**

### 5. 公开且容易找到的联系方式

在 app 的设置里放一个联系邮箱，并在 App Store Connect 里填一个真正有人回复的支持 URL。在 TradaZen 里，支持邮箱写在隐私政策和使用条款里。这些页面应该包含什么，见[app 隐私政策](https://devoria.fr/zh-hans/blog/ios-app-privacy-policy-guide)。

最后一点：决定好用户删除账号后，他的内容如何处理。上面的 `on delete cascade` 会在删除账号时一并删除他的举报记录。完整做法见 [iOS 账号删除](https://devoria.fr/zh-hans/blog/ios-account-deletion-test-before-app-review)。

## TradaZen 在隐私政策里写了什么

这些机制在 TradaZen 的隐私政策里公开说明，这份政策在 2026 年 9 月随联赛和好友功能上线时做了补充：“昵称会经过自动过滤；你可以在排行榜中举报不当昵称，也可以移除并屏蔽好友。”同一份政策还写明，邮箱和交易日志永远不会展示给其他玩家。app 的背景见 [TradaZen 案例分析](https://devoria.fr/zh-hans/blog/tradazen-case-study-launch-iphone-app)。

## 因 1.2 被拒后如何回复 Apple

在回复和审核备注里，告诉审核员每个机制在哪里。这些功能存在于 app 里：审核员测试的是 build 里打包的代码，所以要准备一个新的 build。[回复 App Review](https://developer.apple.com/help/app-store-connect/manage-submissions-to-app-review/reply-to-app-review-messages/) 的流程和其他规则一样。下面是一个英文模板，请根据实际情况修改，只保留你的 app 里真实存在的内容：

```text
Hello,

Thank you for your review. Build X includes the precautions
listed in Guideline 1.2:

- Terms: users accept our terms, with zero tolerance for
  objectionable content and abusive users, before posting.
- Filter: posts and usernames are checked on our server
  before other users can see them.
- Report: tap "..." on any post, then "Report".
- Block: tap "..." on any post, then "Block user". Their
  content disappears immediately.
- Reports notify us instantly; we act on them within 24 hours.
- Contact: Settings > Contact us, and our support URL.

Best regards,
```

如果 build 里缺了某个机制，光回复是没用的。和 [guideline 2.1](https://devoria.fr/zh-hans/blog/app-store-guideline-2-1-rejection-fix) 一样，Apple 评判的是它手上的那个 build。

## 提交前的 1.2 检查清单

- 你已经列出用户发布、且其他人能看到的所有内容，包括昵称。
- 你的使用条款禁止令人反感的内容和滥用行为，app 会要求用户明确点击“我同意”。
- 过滤在服务器上运行，匹配完整的词，并覆盖你商店页面的所有语言。
- 每条内容都有“举报”按钮，每次举报都会立刻通知你。
- 你能在 24 小时内删除内容并封禁发布者。
- 屏蔽一个用户会立即移除他的内容。
- app 里能看到联系邮箱，支持 URL 有人回复。
- 年龄分级问卷里申报了用户内容，如果 app 有消息功能也一并申报。
- 审核备注写明每个机制在哪里，并附上演示账号。

## 重新提交前修复你的拒审问题

如果你的 app 刚因 1.2 被拒，[Review Kit](https://devoria.fr/zh-hans/kits/app-review) 汇集了我每次提交前检查的内容，还附带两个 skill，可以在 Claude Code 里审查你的项目，并在 Apple 拒审时帮你准备回复。如果想让真人帮你看看，[预约和我一对一一小时](https://devoria.fr/zh-hans/coaching)：我们一起读拒审消息，检查你的审核流程。被拒后的完整处理步骤见[被 Apple 拒绝的 app](https://devoria.fr/zh-hans/expertise/app-rejected-by-apple)页面。

如果你正在准备第一次上架，[做一下免费诊断](https://devoria.fr/zh-hans/diagnostic)：它会告诉你先从哪一步入手，并把我的 Apple 防拒审清单发给你。

没有人能保证 Apple 一定会通过你的 app。但把这五个机制做好并清楚地展示出来，至少能把这个拒审原因从清单上划掉。

## 常见问题

### “Guideline 1.2 - Safety - User-Generated Content” 是什么意思？

这是 Apple 拒审消息里的标题。意思是你的 app 展示了用户创建的内容，但没有具备所有要求的保护措施：过滤、及时处理的举报、屏蔽、公开联系方式，以及用户同意的使用条款。

### 排行榜里的昵称算用户内容吗？

Apple 的条文没有明说。我把它当作用户内容处理，因为昵称是自由选择的，而且其他玩家能看到。在 TradaZen 里，排行榜的昵称会经过过滤，可以被举报，出问题时会被替换成中性昵称。

### 真的要在 24 小时内处理举报吗？

Apple 的拒审消息就是这么要求的。规则条文说的是及时响应。所以光有自动过滤是不够的：需要有人去删除内容并封禁发布者。被多次举报后自动隐藏，可以帮你在处理之前先顶住。

### 使用条款必须在 app 内同意吗？

这是最稳妥的做法。拒审消息要求用户同意的条款不容忍令人反感的内容和滥用行为的用户。页面底部的一个链接证明不了用户同意。在第一次发布之前放一个带“我同意”按钮的页面，就不会有疑问。

### 匿名聊天 app 能通过 guideline 1.2 吗？

当前条文把随机或匿名聊天列为不适合上架 App Store 的用途之一。主要用于这类用途的 app 可能被直接下架，恕不另行通知，即使它有过滤、举报和屏蔽功能。


## 你的项目

[Review Kit](https://devoria.fr/zh-hans/kits/app-review)：我的 App Store 审核清单、我被 Apple 拒审后的修正方案、Google Play 审核清单，以及三个 Claude Code skill。¥369。

[iOS & Android Kit](https://devoria.fr/zh-hans/kits/ios)：用 Claude Code 打造你的 iPhone 和 Android 应用：我自己应用的起步代码、上架商店的完整流程，以及全部工具包。¥739。

[诊断：你离自己的 iPhone 应用还差什么](https://devoria.fr/zh-hans/diagnostic)：7 个问题，60 秒：看清真正阻碍你发布 iPhone 应用的原因，拿到你的 4 步路线和适合你的套件。
