Deliver age-appropriate experiences in your app
System Services 进阶 0m

在 App 中提供适龄体验

Deliver age-appropriate experiences in your app

2025年6月9日

在 Apple 官方观看视频

一句话判断

如果你的 App 有用户年龄分级的需求——社交、游戏、内容平台——Declared Age Range API 就是 Apple 给出的官方答案,别再自己做生日输入框了。

这场 Session 讲了什么

Apple 在 iOS 26 推出了 Declared Age Range API,让 App 能以隐私保护的方式获取用户的年龄段,而不是精确生日。核心思路是:App 提交自己关心的年龄节点(比如 13 岁和 16 岁),系统返回一个区间(比如”13 到 15 岁”),而不是精确出生日期。这解决了开发者长期以来的一个两难问题——需要知道用户年龄来做内容分级,但又不想承担存储精确生日的隐私风险。

Session 围绕三个层面展开:背景政策(Apple 2025 年的儿童保护白皮书、App Store 年龄分级从三档变五档)、框架机制(Declared Age Range 框架的请求-响应模型、缓存策略、家长控制集成),以及实际代码(如何在 SwiftUI 中接入,如何处理分享/拒绝/错误三种情况)。

值得深挖的点

隐私优先的年龄区间设计

这个 API 最巧妙的地方在于”只说必要的”。App 声明自己关心的年龄节点,系统通过区间划分来避免暴露精确生日。比如你关心 13 和 16 两个节点,系统会把用户分成”12 及以下""13-15""16 及以上”三档。一个 14 岁的用户只会暴露”13-15”这个信息。更关键的是,系统还会做”周年日缓存”——即使用户刚满 13 岁跨越了新的区间,API 在周年纪念日之前仍然返回旧的区间值,以防止通过时间差反推出精确生日。这个细节说明 Apple 在隐私保护上确实想得很深。

家长控制的三层粒度

API 提供了三种家长设置:Always Share(自动返回)、Ask First(每次弹窗询问)、Never Share(始终拒绝)。对于 Always Share 模式,新年龄信息也只在周年日才刷新。家长还可以在设置中强制清除缓存,让 App 立即获取最新年龄。对于 16 岁以下的用户,API 还会额外返回家长已配置的控制项(如通信限制),让 App 能进一步适配。

ageRangeDeclaration 字段

返回值中有一个 ageRangeDeclaration 字段,标识年龄数据来源是 guardianDeclared(家长声明)还是 selfDeclared(用户自行声明)。儿童账户永远是 guardianDeclared;青少年如果在 iCloud 家庭中也是 guardianDeclared,不在家庭中则是 selfDeclared;成人始终是 selfDeclared。这个字段对需要合规审计的场景很有用。

代码片段

1. 基础请求:判断用户是否 16 岁以上

场景:照片分享功能需要 16 岁以上才能使用。

import DeclaredAgeRange

func requestAgeRangeHelper() async {
    do {
        let response = try await DeclaredAgeRange.requestAgeRange(ages: [16])
        switch response {
        case .sharing(let ageRange):
            if let lowerBound = ageRange.lowerBound, lowerBound >= 16 {
                // 启用照片分享功能
                isPhotoSharingEnabled = true
            }
        case .declineSharing:
            // 用户拒绝分享,功能保持禁用
            break
        }
    } catch DeclaredAgeRangeError.invalidRequest {
        // 请求参数有问题,检查 age range 是否至少两年
    } catch DeclaredAgeRangeError.notAvailable {
        // 设备未登录 Apple 账户等
    } catch {}
}

坑:每个区间必须至少两年长度,最多三个节点(产生四个区间)。区域不同成年人年龄上限也不同,API 会自动处理。

2. 多节点请求:精细分级

场景:社交 App 需要对 13 岁以下、13-15 岁、16 岁以上提供不同体验。

let response = try await DeclaredAgeRange.requestAgeRange(ages: [13, 16])
// 返回的 lowerBound/upperBound 可能是 nil
// nil lowerBound 表示"最小年龄段"
// nil upperBound 表示"最大年龄段"(通常是 16+)

最佳实践

接入 Declared Age Range API 的第一步是确定你需要哪些年龄节点。不要贪多——每个节点都会增加区间划分的复杂度。从你的合规需求出发:哪些功能有法定年龄限制?通常 13(COPPA)和 16(GDPR)就够了。

请求时机上,建议在功能入口处按需请求,而不是 App 启动时全量请求。API 有缓存机制,同一用户短期内不会重复弹窗,所以不用担心频繁请求打扰用户。

处理 decline sharing 的情况时,不要粗暴地拒绝所有功能——可以降级体验,比如隐藏社交分享但保留浏览功能。毕竟用户(或家长)选择不分享年龄并不等于他们是儿童。

还有什么值得关注

  • Sensitive Content Analysis API 扩展:iOS 26 新增了对实时视频通话中的裸露内容检测,如果你的 App 有视频通话功能,需要关注。
  • App Store 年龄分级变更:从三档变成五档(4+/9+/13+/16+/18+),影响所有 App 的元数据配置。
  • PermissionKit(Session 提到):用于让家长控制孩子在第三方 App 中的通信权限,社交类 App 应该关注。
系统服务 隐私与安全