Skip to content

Commit e46dac5

Browse files
authored
Only request App Tracking Transparency when app is active (#751)
1 parent db42382 commit e46dac5

File tree

4 files changed

+39
-26
lines changed

4 files changed

+39
-26
lines changed

README.md

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -955,26 +955,6 @@ When requesting `PERMISSIONS.IOS.LOCATION_ALWAYS`, if the user choose `Allow Whi
955955

956956
Subsequently, if you are requesting `LOCATION_ALWAYS` permission, there is no need to request `LOCATION_WHEN_IN_USE`. If the user accepts, `LOCATION_WHEN_IN_USE` will be granted too. If the user denies, `LOCATION_WHEN_IN_USE` will be denied too.
957957

958-
### How to request "App Tracking Transparency" permission on iOS
959-
960-
Since iOS 15.0, it's impossible to request this permission if the app isn't `active` (see [#648](https://github.com/zoontek/react-native-permissions/issues/648)). A good solution is to use `AppState` to make sure this is the case:
961-
962-
```js
963-
useEffect(() => {
964-
const callback = (status: AppStateStatus) => {
965-
if (status === 'active') {
966-
request(PERMISSIONS.IOS.APP_TRACKING_TRANSPARENCY)
967-
.then((result) => console.log(result))
968-
.catch((error) => console.log(error));
969-
}
970-
};
971-
972-
callback(AppState.currentState); // initial call
973-
const listener = AppState.addEventListener('change', callback);
974-
return listener.remove;
975-
}, []);
976-
```
977-
978958
### Testing with Jest
979959

980960
If you don't already have a Jest setup file configured, please add the following to your Jest configuration file and create the new `jest.setup.js` file in project root:

ios/AppTrackingTransparency/RNPermissionHandlerAppTrackingTransparency.m

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33
@import AppTrackingTransparency;
44
@import AdSupport;
55

6+
@interface RNPermissionHandlerAppTrackingTransparency()
7+
8+
@property (nonatomic, strong) void (^resolve)(RNPermissionStatus status);
9+
@property (nonatomic, strong) void (^reject)(NSError *error);
10+
11+
@end
12+
613
@implementation RNPermissionHandlerAppTrackingTransparency
714

815
+ (NSArray<NSString *> * _Nonnull)usageDescriptionKeys {
@@ -38,12 +45,38 @@ - (void)checkWithResolver:(void (^ _Nonnull)(RNPermissionStatus))resolve
3845
- (void)requestWithResolver:(void (^ _Nonnull)(RNPermissionStatus))resolve
3946
rejecter:(void (^ _Nonnull)(NSError * _Nonnull))reject {
4047
if (@available(iOS 14.0, *)) {
41-
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(__unused ATTrackingManagerAuthorizationStatus status) {
42-
[self checkWithResolver:resolve rejecter:reject];
43-
}];
48+
if ([ATTrackingManager trackingAuthorizationStatus] != ATTrackingManagerAuthorizationStatusNotDetermined) {
49+
return [self checkWithResolver:resolve rejecter:reject];
50+
}
51+
52+
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive) {
53+
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(__unused ATTrackingManagerAuthorizationStatus status) {
54+
[self checkWithResolver:resolve rejecter:reject];
55+
}];
56+
} else {
57+
_resolve = resolve;
58+
_reject = reject;
59+
60+
[[NSNotificationCenter defaultCenter] addObserver:self
61+
selector:@selector(onApplicationDidBecomeActive:)
62+
name:UIApplicationDidBecomeActiveNotification
63+
object:nil];
64+
}
4465
} else {
4566
[self checkWithResolver:resolve rejecter:reject];
4667
}
4768
}
4869

70+
- (void)onApplicationDidBecomeActive:(__unused NSNotification *)notification {
71+
[[NSNotificationCenter defaultCenter] removeObserver:self
72+
name:UIApplicationDidBecomeActiveNotification
73+
object:nil];
74+
75+
if (@available(iOS 14.0, *)) {
76+
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(__unused ATTrackingManagerAuthorizationStatus status) {
77+
[self checkWithResolver:self->_resolve rejecter:self->_reject];
78+
}];
79+
}
80+
}
81+
4982
@end

ios/FaceID/RNPermissionHandlerFaceID.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ - (void)requestWithResolver:(void (^ _Nonnull)(RNPermissionStatus))resolve
7676
_laContext = context;
7777

7878
[[NSNotificationCenter defaultCenter] addObserver:self
79-
selector:@selector(UIApplicationDidBecomeActiveNotification:)
79+
selector:@selector(onApplicationDidBecomeActive:)
8080
name:UIApplicationDidBecomeActiveNotification
8181
object:nil];
8282

@@ -95,7 +95,7 @@ - (void)invalidateContext {
9595
[_laContext invalidate];
9696
}
9797

98-
- (void)UIApplicationDidBecomeActiveNotification:(__unused NSNotification *)notification {
98+
- (void)onApplicationDidBecomeActive:(__unused NSNotification *)notification {
9999
[[NSNotificationCenter defaultCenter] removeObserver:self
100100
name:UIApplicationDidBecomeActiveNotification
101101
object:nil];

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-permissions",
3-
"version": "3.7.0",
3+
"version": "3.7.1",
44
"license": "MIT",
55
"description": "An unified permissions API for React Native on iOS, Android and Windows",
66
"author": "Mathieu Acthernoene <[email protected]>",

0 commit comments

Comments
 (0)