You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS Expo项目App Tracking Transparency弹窗不显示问题

问题成因
  • 触发时机违反iOS系统规则:从iOS 15开始,系统明确拦截应用冷启动阶段直接发起的ATT权限请求,只要是应用启动后首个运行循环内触发的requestTrackingPermissionsAsync调用,系统会直接静默拦截,不渲染任何弹窗。你把请求逻辑放在App.js根组件的空依赖useEffect中,刚好属于应用刚挂载的启动节点,必然被拦截。iOS模拟器对ATT的校验逻辑做了简化,不会触发这个拦截规则,所以会出现模拟器弹窗正常、TestFlight/真机/审核环境完全不弹的现象,这也是你收到审核驳回的核心原因。
  • 打包配置缺失:如果expo配置中没有正确声明NSUserTrackingUsageDescription权限文案,或者没有配置expo-tracking-transparency的原生插件,EAS云打包后会丢失权限相关配置,真机环境下同样不会弹出权限窗。
  • 测试环境缓存干扰:如果你测试TestFlight包的设备之前安装过同Bundle ID的应用,已经做过跟踪权限选择,系统会记住权限状态,不会重复弹出弹窗,容易造成“代码不生效”的误判。
解决方案

按以下步骤逐一排查调整即可通过审核:

  1. 调整权限请求触发时机
    绝对不要在应用启动的初始生命周期调用ATT请求,必须等应用完成首屏渲染、所有启动初始化逻辑执行完毕后,再延迟至少1s触发,更稳妥的方式是把请求绑定到用户的主动交互行为(比如点击首页的“进入应用”“同意隐私协议”按钮)。
    修正后的参考代码:
import { useEffect, useState } from 'react';
import { requestTrackingPermissionsAsync, getTrackingPermissionsAsync } from 'expo-tracking-transparency';

export default function App() {
  const [appInitFinished, setAppInitFinished] = useState(false);

  // 先执行所有应用初始化逻辑:字体加载、隐私协议弹窗展示、路由挂载等
  useEffect(() => {
    async function initApp() {
      // 这里放你原来的启动初始化逻辑,比如加载资源、检查版本等
      setAppInitFinished(true);
    }
    initApp();
  }, []);

  // 初始化完成后延迟触发权限请求,避开系统的启动拦截规则
  useEffect(() => {
    if (!appInitFinished) return;
    // 延迟1.5s,确保完全离开应用启动的生命周期节点
    const reqTimer = setTimeout(async () => {
      // 先判断是否还能发起权限请求,避免重复调用
      const { canRequest } = await getTrackingPermissionsAsync();
      if (canRequest) {
        const { status } = await requestTrackingPermissionsAsync();
        if (status === 'granted') {
          console.log('已获取跟踪权限');
        }
      }
    }, 1500);

    return () => clearTimeout(reqTimer);
  }, [appInitFinished]);

  // 原有应用渲染逻辑
}
  1. 校验expo原生配置
    打开项目根目录的app.json,确保配置了权限文案和对应插件,避免打包后配置丢失:
{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSUserTrackingUsageDescription": "该权限将用于为您推荐个性化内容、优化广告体验,不会收集无关个人信息"
      }
    },
    "plugins": [
      [
        "expo-tracking-transparency",
        {
          "userTrackingPermission": "该权限将用于为您推荐个性化内容、优化广告体验,不会收集无关个人信息"
        }
      ]
    ]
  }
}

配置完成后执行eas build -p ios重新打TestFlight包,不要使用之前的缓存构建版本。

  1. 正确验证功能有效性
  • 不要用iOS模拟器作为ATT功能的验证环境,必须用真机测试:测试前先完全卸载设备上所有同Bundle ID的旧版本应用,打开系统设置-隐私与安全性-跟踪,开启“允许App请求跟踪”总开关后,再安装新打的TestFlight包验证。
  • 如果审核被拒,在申诉备注里可以说明权限请求的触发位置,方便审核员找到弹窗触发节点。

内容的提问来源于stack exchange,提问作者Hugo marangao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 18:24:35