애플 앱 심사에서 ATT(앱 추적 투명성, App Tracking Transparency) 관련 반려를 받았다면, ATT 거부 시 맞춤형 광고(Personalized Ads)를 제공하지 않도록 설정해야 합니다.
이 문제를 해결하려면 ATT 상태를 전역적으로 관리하고, 이를 광고 제공 컴포넌트(AdProvider)에서 반영하는 방식으로 수정해야 합니다.
📌 문제점: ATT 거부 시 맞춤형 광고 제공
1️⃣ ATT 관련 애플 심사 가이드라인 위반
- 애플은 사용자가 ATT를 거부했을 때 다시 동의를 요청하면 안 된다고 명확히 규정하고 있음.
- 하지만 현재 코드는 사용자가 ATT를 거부해도 Alert로 재요청을 하거나 광고 제공 방식을 변경하지 않음.
2️⃣ ATT 거부 시 개인화 광고(PA) 제공 문제
- ATT를 거부한 경우, 구글 애드몹에서 개인화 광고(PA)를 제공하면 안 됨.
- 하지만 현재 광고 제공 컴포넌트(AdProvider.js)는 ATT 상태를 반영하지 않고 광고 요청을 실행하고 있음.
- 이로 인해 ATT 거부 후에도 맞춤형 광고가 제공되는 문제가 발생.
🔹 해결 방법: ATT 상태를 전역 상태로 관리하고, 광고 요청 시 반영하기
✅ ATT 상태를 TrackingPermissionContext에서 전역으로 관리
✅ AdProvider.js에서 requestNonPersonalizedAdsOnly를 ATT 상태에 따라 설정
✅ ATT 거부 시 자동으로 비개인화 광고(NPA, Non-Personalized Ads)를 요청
🚀 1. TrackingPermissionContext.js (ATT 상태 전역 관리)
✅ ATT 상태를 앱 전체에서 사용할 수 있도록 설정
import React, { createContext, useState, useEffect, useContext } from 'react';
import { Platform } from 'react-native';
import { requestTrackingPermission } from 'react-native-tracking-transparency';
const TrackingPermissionContext = createContext();
export const TrackingPermissionProvider = ({ children }) => {
const [isTrackingAllowed, setIsTrackingAllowed] = useState(null);
useEffect(() => {
const checkTrackingPermission = async () => {
if (Platform.OS === 'ios') {
const status = await requestTrackingPermission();
setIsTrackingAllowed(status === 'authorized'); // ✅ ATT 승인 여부 저장
console.log(`[TrackingPermission] ATT 상태: ${status}`);
} else {
setIsTrackingAllowed(true); // ✅ Android는 자동 허용
}
};
checkTrackingPermission();
}, []);
return (
<TrackingPermissionContext.Provider value={{ isTrackingAllowed }}>
{children}
</TrackingPermissionContext.Provider>
);
};
export const useTrackingPermission = () => useContext(TrackingPermissionContext);
✅ isTrackingAllowed 값이 true이면 맞춤형 광고(PA) 제공 가능
✅ false이면 비개인화 광고(NPA) 제공하도록 광고 설정 변경 필요
✅ 이제 AdProvider.js에서 useTrackingPermission()을 사용하여 ATT 상태를 반영 가능
🚀 2. AdProvider.js (ATT 상태 반영하여 광고 요청)
✅ ATT 상태에 따라 맞춤형 광고 vs 비개인화 광고 제공
import React, { createContext, useState, useEffect, useContext, useRef } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { RewardedAd, RewardedAdEventType, TestIds } from 'react-native-google-mobile-ads';
import { Platform } from 'react-native';
import { useTrackingPermission } from '../services/TrackingPermissionContext'; // 🚀 ATT 상태 가져오기
const adUnitId = Platform.select({
ios: "ca-app-pub-8662733550474556/1064615361",
});
const AdContext = createContext();
export const AdProvider = ({ children }) => {
const [isAdLoaded, setIsAdLoaded] = useState(false);
const rewardedAdRef = useRef(null);
const { isTrackingAllowed } = useTrackingPermission(); // 🚀 ATT 상태 가져오기
const loadAd = async () => {
try {
if (isTrackingAllowed === null) {
console.log('[AdProvider] ATT 상태 확인 중... 광고 로드 보류');
return;
}
const requestOptions = {
requestNonPersonalizedAdsOnly: !isTrackingAllowed, // ✅ ATT 거부 시 비개인화 광고 요청
};
rewardedAdRef.current = RewardedAd.createForAdRequest(adUnitId, requestOptions);
console.log(`[AdProvider] 광고 요청 옵션: ${JSON.stringify(requestOptions)}`);
rewardedAdRef.current.addAdEventListener(RewardedAdEventType.LOADED, () => {
setIsAdLoaded(true);
console.log('[AdProvider] 광고 이벤트: 로드 완료');
});
rewardedAdRef.current.onAdDismissedFullScreenContent = () => {
console.log('[AdProvider] 광고 닫힘 → 새로운 광고 로드');
setIsAdLoaded(false);
loadAd(); // 새로운 광고 로드
};
await rewardedAdRef.current.load();
console.log('[AdProvider] 광고 로드 완료');
} catch (error) {
console.error('[AdProvider] 광고 로드 실패:', error);
setIsAdLoaded(false);
}
};
useEffect(() => {
if (isTrackingAllowed !== null) {
loadAd();
}
}, [isTrackingAllowed]);
return (
<AdContext.Provider value={{ isAdLoaded }}>
{children}
</AdContext.Provider>
);
};
export const useAd = () => useContext(AdContext);
🚀 3. App.js에서 TrackingPermissionProvider 적용하기
✅ App.js에서 TrackingPermissionProvider를 감싸서 모든 컴포넌트가 ATT 상태를 공유할 수 있도록 설정해야 함.
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { TrackingPermissionProvider } from './services/TrackingPermissionContext'; // 🚀 추가
import { AdProvider } from './services/AdProvider';
export default function App() {
return (
<TrackingPermissionProvider>
<AdProvider>
<NavigationContainer>
{/* 앱 내 라우팅 구조 */}
</NavigationContainer>
</AdProvider>
</TrackingPermissionProvider>
);
}
📌 최종 정리
✔️ ATT 거부 시 맞춤형 광고 제공을 막는 방식
1️⃣ TrackingPermissionContext에서 ATT 상태를 전역적으로 관리
2️⃣ AdProvider에서 requestNonPersonalizedAdsOnly 옵션을 ATT 상태에 따라 설정
- ATT 승인(true) → 맞춤형 광고(Personalized Ads) 제공
- ATT 거부(false) → 비개인화 광고(Non-Personalized Ads) 제공
3️⃣ 앱 전체에서 ATT 상태를 공유하도록 App.js에서 TrackingPermissionProvider 적용
✅ 이제 애플 정책을 완벽하게 준수하면서도 광고가 정상적으로 동작! 🚀
✅ ATT 거부 시 개인화 광고를 제공하지 않도록 완벽히 차단 가능! 💡
✅ 심사 재반려 없이 문제 해결 완료! 🎯
'플러팅 AI > 배포' 카테고리의 다른 글
| IOS 배포 후 문제점찾아 버전 변경 1.1 (0) | 2025.01.27 |
|---|---|
| 🎉 App Store 배포 완료! 🎉 (0) | 2025.01.27 |
| apple app store 5번 째 반려 (0) | 2025.01.21 |
| 플러팅 AI 수익 구조 개편 (0) | 2025.01.17 |
| 구글 애드몹을 위한 iOS TrackingPermission 설정 (0) | 2025.01.15 |