1import { 2 PermissionResponse, 3 PermissionStatus, 4 PermissionExpiration, 5 PermissionHookOptions, 6 UnavailabilityError, 7 createPermissionHook, 8} from 'expo-modules-core'; 9import { Platform } from 'react-native'; 10 11import ExpoTrackingTransparency from './ExpoTrackingTransparency'; 12 13const androidAndWebPermissionsResponse: PermissionResponse = { 14 granted: true, 15 expires: 'never', 16 canAskAgain: true, 17 status: PermissionStatus.GRANTED, 18}; 19 20/** 21 * Requests the user to authorize or deny access to app-related data that can be used for tracking 22 * the user or the device. Examples of data used for tracking include email address, device ID, 23 * advertising ID, etc. On iOS 14.5 and above, if the user denies this permission, any attempt to 24 * collect the IDFA will return a string of 0s. 25 * 26 * The system remembers the user’s choice and doesn’t prompt again unless a user uninstalls and then 27 * reinstalls the app on the device. 28 * 29 * On Android, web, and iOS 13 and below, this method always returns that the permission was 30 * granted. 31 * @example 32 * ```typescript 33 * const { granted } = await requestTrackingPermissionsAsync(); 34 * 35 * if (granted) { 36 * // Your app is authorized to track the user or their device 37 * } 38 * ``` 39 */ 40export async function requestTrackingPermissionsAsync(): Promise<PermissionResponse> { 41 if (Platform.OS !== 'ios') { 42 return Promise.resolve(androidAndWebPermissionsResponse); 43 } 44 45 if (!ExpoTrackingTransparency.requestPermissionsAsync) { 46 throw new UnavailabilityError('TrackingTransparency', 'requestPermissionsAsync'); 47 } 48 return await ExpoTrackingTransparency.requestPermissionsAsync(); 49} 50 51/** 52 * Checks whether or not the user has authorized the app to access app-related data that can be used 53 * for tracking the user or the device. See `requestTrackingPermissionsAsync` for more details. 54 * 55 * On Android, web, and iOS 13 and below, this method always returns that the permission was 56 * granted. 57 * 58 * @example 59 * ```typescript 60 * const { granted } = await getTrackingPermissionsAsync(); 61 * 62 * if (granted) { 63 * // Your app is authorized to track the user or their device 64 * } 65 * ``` 66 */ 67export async function getTrackingPermissionsAsync(): Promise<PermissionResponse> { 68 if (Platform.OS !== 'ios') { 69 return Promise.resolve(androidAndWebPermissionsResponse); 70 } 71 72 if (!ExpoTrackingTransparency.getPermissionsAsync) { 73 throw new UnavailabilityError('TrackingTransparency', 'getPermissionsAsync'); 74 } 75 return await ExpoTrackingTransparency.getPermissionsAsync(); 76} 77 78/** 79 * Check or request the user to authorize or deny access to app-related data that can be used for tracking 80 * the user or the device. Examples of data used for tracking include email address, device ID, 81 * advertising ID, etc. On iOS 14.5 and above, if the user denies this permission, any attempt to 82 * collect the IDFA will return a string of 0s. 83 * 84 * The system remembers the user’s choice and doesn’t prompt again unless a user uninstalls and then 85 * reinstalls the app on the device. 86 * 87 * On Android, web, and iOS 13 and below, this method always returns that the permission was 88 * granted. 89 * @example 90 * ```ts 91 * const [status, requestPermission] = useTrackingPermissions(); 92 * ``` 93 */ 94export const useTrackingPermissions = createPermissionHook({ 95 getMethod: getTrackingPermissionsAsync, 96 requestMethod: requestTrackingPermissionsAsync, 97}); 98 99/** 100 * Returns whether the TrackingTransparency API is available on the current device. 101 * 102 * @returns Currently this is `true` on iOS 14 and above only. On devices where the 103 * Tracking Transparency API is unavailable, the get and request permissions methods will always 104 * resolve to `granted`. 105 */ 106export function isAvailable(): boolean { 107 return ( 108 Platform.OS === 'ios' && 109 parseInt(Platform.Version.toString(), 10) >= 14 && 110 ExpoTrackingTransparency 111 ); 112} 113 114export { PermissionResponse, PermissionStatus, PermissionExpiration, PermissionHookOptions }; 115