Skip to content

Commit

Permalink
Improve tvOS compat (#907)
Browse files Browse the repository at this point in the history
  • Loading branch information
zoontek authored Nov 20, 2024
1 parent c42e2bc commit ac0eb65
Show file tree
Hide file tree
Showing 20 changed files with 155 additions and 39 deletions.
4 changes: 2 additions & 2 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1575,7 +1575,7 @@ PODS:
- React-logger (= 0.76.2)
- React-perflogger (= 0.76.2)
- React-utils (= 0.76.2)
- RNPermissions (5.1.0):
- RNPermissions (5.2.0):
- DoubleConversion
- glog
- hermes-engine
Expand Down Expand Up @@ -1893,7 +1893,7 @@ SPEC CHECKSUMS:
React-utils: c8c0c746031419a29cfd8c72a394fdeac0684a84
ReactCodegen: a64e8f3a8bba0ecf88fce06c2874e021d55148f3
ReactCommon: 7b9403030ff3430ccffed63cd25c8aeab2a3ea7e
RNPermissions: 669997f76d2e3552b56ae66dc1b1f8d6363fa39e
RNPermissions: 28282c8a8d486a6df4c0bcca76bf748212f5610c
RNVectorIcons: a24016b773380b1aa37fca501ec6b94a951890a0
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
Yoga: 96872ee462cfc43866ad013c8160d4ff6b85709b
Expand Down
10 changes: 8 additions & 2 deletions example/ios/RNPermissionsExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,10 @@
"-DFOLLY_CFG_NO_COROUTINES=1",
"-DFOLLY_HAVE_CLOCK_GETTIME=1",
);
OTHER_LDFLAGS = "$(inherited) ";
OTHER_LDFLAGS = (
"$(inherited)",
" ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
Expand Down Expand Up @@ -453,7 +456,10 @@
"-DFOLLY_CFG_NO_COROUTINES=1",
"-DFOLLY_HAVE_CLOCK_GETTIME=1",
);
OTHER_LDFLAGS = "$(inherited) ";
OTHER_LDFLAGS = (
"$(inherited)",
" ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
USE_HERMES = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ - (RNPermissionStatus)convertStatus:(ATTrackingManagerAuthorizationStatus)status
}

- (RNPermissionStatus)currentStatus {
if (@available(iOS 14.0, *)) {
if (@available(iOS 14.0, tvOS 14.0, *)) {
return [self convertStatus:[ATTrackingManager trackingAuthorizationStatus]];
} else {
if ([[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]) {
Expand All @@ -46,7 +46,7 @@ - (RNPermissionStatus)currentStatus {

- (void)requestWithResolver:(void (^ _Nonnull)(RNPermissionStatus))resolve
rejecter:(void (^ _Nonnull)(NSError * _Nonnull))reject {
if (@available(iOS 14.0, *)) {
if (@available(iOS 14.0, tvOS 14.0, *)) {
if ([ATTrackingManager trackingAuthorizationStatus] != ATTrackingManagerAuthorizationStatusNotDetermined) {
return resolve([self currentStatus]);
}
Expand All @@ -73,7 +73,7 @@ - (void)onApplicationDidBecomeActive:(__unused NSNotification *)notification {
name:UIApplicationDidBecomeActiveNotification
object:nil];

if (@available(iOS 14.0, *)) {
if (@available(iOS 14.0, tvOS 14.0, *)) {
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
self->_resolve([self convertStatus:status]);
}];
Expand Down
4 changes: 2 additions & 2 deletions ios/Bluetooth/RNPermissionHandlerBluetooth.mm
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ + (NSString * _Nonnull)handlerUniqueId {
}

- (RNPermissionStatus)currentStatus {
#if TARGET_OS_SIMULATOR
#if TARGET_OS_TV || TARGET_OS_SIMULATOR
return RNPermissionStatusNotAvailable;
#else
switch ([CBManager authorization]) {
Expand All @@ -41,7 +41,7 @@ - (RNPermissionStatus)currentStatus {

- (void)requestWithResolver:(void (^ _Nonnull)(RNPermissionStatus))resolve
rejecter:(void (^ _Nonnull)(NSError * _Nonnull))reject {
#if TARGET_OS_SIMULATOR
#if TARGET_OS_TV || TARGET_OS_SIMULATOR
return resolve(RNPermissionStatusNotAvailable);
#else
_resolve = resolve;
Expand Down
10 changes: 10 additions & 0 deletions ios/Calendars/RNPermissionHandlerCalendars.mm
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#import "RNPermissionHandlerCalendars.h"

#if !TARGET_OS_TV
#import <EventKit/EventKit.h>
#endif

@implementation RNPermissionHandlerCalendars

Expand All @@ -13,6 +15,9 @@ + (NSString * _Nonnull)handlerUniqueId {
}

- (RNPermissionStatus)currentStatus {
#if TARGET_OS_TV
return RNPermissionStatusNotAvailable;
#else
switch ([EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent]) {
case EKAuthorizationStatusNotDetermined:
return RNPermissionStatusNotDetermined;
Expand All @@ -25,10 +30,14 @@ - (RNPermissionStatus)currentStatus {
case EKAuthorizationStatusFullAccess:
return RNPermissionStatusAuthorized;
}
#endif
}

- (void)requestWithResolver:(void (^ _Nonnull)(RNPermissionStatus))resolve
rejecter:(void (^ _Nonnull)(NSError * _Nonnull))reject {
#if TARGET_OS_TV
resolve(RNPermissionStatusNotAvailable);
#else
EKEventStore *store = [EKEventStore new];

void (^completion)(BOOL, NSError * _Nullable) = ^(__unused BOOL granted, NSError * _Nullable error) {
Expand Down Expand Up @@ -56,6 +65,7 @@ - (void)requestWithResolver:(void (^ _Nonnull)(RNPermissionStatus))resolve
} else {
[store requestAccessToEntityType:EKEntityTypeEvent completion:completion];
}
#endif
}

@end
10 changes: 10 additions & 0 deletions ios/CalendarsWriteOnly/RNPermissionHandlerCalendarsWriteOnly.mm
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#import "RNPermissionHandlerCalendarsWriteOnly.h"

#if !TARGET_OS_TV
#import <EventKit/EventKit.h>
#endif

@implementation RNPermissionHandlerCalendarsWriteOnly

Expand All @@ -13,6 +15,9 @@ + (NSString * _Nonnull)handlerUniqueId {
}

- (RNPermissionStatus)currentStatus {
#if TARGET_OS_TV
return RNPermissionStatusNotAvailable;
#else
switch ([EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent]) {
case EKAuthorizationStatusNotDetermined:
return RNPermissionStatusNotDetermined;
Expand All @@ -24,10 +29,14 @@ - (RNPermissionStatus)currentStatus {
case EKAuthorizationStatusFullAccess:
return RNPermissionStatusAuthorized;
}
#endif
}

- (void)requestWithResolver:(void (^ _Nonnull)(RNPermissionStatus))resolve
rejecter:(void (^ _Nonnull)(NSError * _Nonnull))reject {
#if TARGET_OS_TV
resolve(RNPermissionStatusNotAvailable);
#else
EKEventStore *store = [EKEventStore new];

void (^completion)(BOOL, NSError * _Nullable) = ^(__unused BOOL granted, NSError * _Nullable error) {
Expand All @@ -43,6 +52,7 @@ - (void)requestWithResolver:(void (^ _Nonnull)(RNPermissionStatus))resolve
} else {
[store requestAccessToEntityType:EKEntityTypeEvent completion:completion];
}
#endif
}

@end
32 changes: 20 additions & 12 deletions ios/Camera/RNPermissionHandlerCamera.mm
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,32 @@ + (NSString * _Nonnull)handlerUniqueId {
}

- (RNPermissionStatus)currentStatus {
switch ([AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo]) {
case AVAuthorizationStatusNotDetermined:
return RNPermissionStatusNotDetermined;
case AVAuthorizationStatusRestricted:
return RNPermissionStatusRestricted;
case AVAuthorizationStatusDenied:
return RNPermissionStatusDenied;
case AVAuthorizationStatusAuthorized:
return RNPermissionStatusAuthorized;
if (@available(iOS 7.0, tvOS 17.0, *)) {
switch ([AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo]) {
case AVAuthorizationStatusNotDetermined:
return RNPermissionStatusNotDetermined;
case AVAuthorizationStatusRestricted:
return RNPermissionStatusRestricted;
case AVAuthorizationStatusDenied:
return RNPermissionStatusDenied;
case AVAuthorizationStatusAuthorized:
return RNPermissionStatusAuthorized;
}
} else {
return RNPermissionStatusNotAvailable;
}
}

- (void)requestWithResolver:(void (^ _Nonnull)(RNPermissionStatus))resolve
rejecter:(void (^ _Nonnull)(NSError * _Nonnull))reject {
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo
completionHandler:^(__unused BOOL granted) {
if (@available(iOS 7.0, tvOS 17.0, *)) {
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo
completionHandler:^(__unused BOOL granted) {
resolve([self currentStatus]);
}];
} else {
resolve([self currentStatus]);
}];
}
}

@end
10 changes: 10 additions & 0 deletions ios/Contacts/RNPermissionHandlerContacts.mm
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#import "RNPermissionHandlerContacts.h"

#if !TARGET_OS_TV
#import <Contacts/Contacts.h>
#endif

@implementation RNPermissionHandlerContacts

Expand All @@ -13,6 +15,9 @@ + (NSString * _Nonnull)handlerUniqueId {
}

- (RNPermissionStatus)currentStatus {
#if TARGET_OS_TV
return RNPermissionStatusNotAvailable;
#else
switch ([CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts]) {
case CNAuthorizationStatusNotDetermined:
return RNPermissionStatusNotDetermined;
Expand All @@ -25,10 +30,14 @@ - (RNPermissionStatus)currentStatus {
case CNAuthorizationStatusAuthorized:
return RNPermissionStatusAuthorized;
}
#endif
}

- (void)requestWithResolver:(void (^ _Nonnull)(RNPermissionStatus))resolve
rejecter:(void (^ _Nonnull)(NSError * _Nonnull))reject {
#if TARGET_OS_TV
resolve(RNPermissionStatusNotAvailable);
#else
[[CNContactStore new] requestAccessForEntityType:CNEntityTypeContacts
completionHandler:^(__unused BOOL granted, NSError * _Nullable error) {
if (error != nil && error.code != 100) { // error code 100 is permission denied
Expand All @@ -37,6 +46,7 @@ - (void)requestWithResolver:(void (^ _Nonnull)(RNPermissionStatus))resolve
resolve([self currentStatus]);
}
}];
#endif
}

@end
15 changes: 15 additions & 0 deletions ios/FaceID/RNPermissionHandlerFaceID.mm
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

@interface RNPermissionHandlerFaceID()

#if !TARGET_OS_TV
@property (nonatomic, strong) LAContext *laContext;
@property (nonatomic, strong) void (^resolve)(RNPermissionStatus status);
#endif

@end

Expand All @@ -20,6 +22,9 @@ + (NSString * _Nonnull)handlerUniqueId {
}

- (RNPermissionStatus)currentStatus {
#if TARGET_OS_TV
return RNPermissionStatusNotAvailable;
#else
LAContext *context = [LAContext new];
NSError *error;

Expand All @@ -42,10 +47,14 @@ - (RNPermissionStatus)currentStatus {
}

return RNPermissionStatusAuthorized;
#endif
}

- (void)requestWithResolver:(void (^ _Nonnull)(RNPermissionStatus))resolve
rejecter:(void (^ _Nonnull)(NSError * _Nonnull))reject {
#if TARGET_OS_TV
resolve(RNPermissionStatusNotAvailable);
#else
LAContext *context = [LAContext new];
NSError *error;

Expand Down Expand Up @@ -77,10 +86,13 @@ - (void)requestWithResolver:(void (^ _Nonnull)(RNPermissionStatus))resolve

// Hack to invalidate FaceID verification immediately after being requested
[self performSelector:@selector(invalidateContext) withObject:self afterDelay:0.05];
#endif
}

- (void)invalidateContext {
#if !TARGET_OS_TV
[_laContext invalidate];
#endif
}

- (void)onApplicationDidBecomeActive:(__unused NSNotification *)notification {
Expand All @@ -89,7 +101,10 @@ - (void)onApplicationDidBecomeActive:(__unused NSNotification *)notification {
object:nil];

[RNPermissions flagAsRequested:[[self class] handlerUniqueId]];

#if !TARGET_OS_TV
_resolve([self currentStatus]);
#endif
}

@end
4 changes: 2 additions & 2 deletions ios/LocationAccuracy/RNPermissionHandlerLocationAccuracy.mm
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ + (NSString * _Nonnull)handlerUniqueId {

- (void)checkWithResolver:(RCTPromiseResolveBlock _Nonnull)resolve
rejecter:(RCTPromiseRejectBlock _Nonnull)reject {
if (@available(iOS 14.0, *)) {
if (@available(iOS 14.0, tvOS 14.0, *)) {
switch ([CLLocationManager authorizationStatus]) {
case kCLAuthorizationStatusNotDetermined:
return reject(@"cannot_check_location_accuracy", @"Location permission hasn't been requested first", nil);
Expand Down Expand Up @@ -42,7 +42,7 @@ - (void)checkWithResolver:(RCTPromiseResolveBlock _Nonnull)resolve
- (void)requestWithPurposeKey:(NSString * _Nonnull)purposeKey
resolver:(RCTPromiseResolveBlock _Nonnull)resolve
rejecter:(RCTPromiseRejectBlock _Nonnull)reject {
if (@available(iOS 14.0, *)) {
if (@available(iOS 14.0, tvOS 14.0, *)) {
switch ([CLLocationManager authorizationStatus]) {
case kCLAuthorizationStatusNotDetermined:
return reject(@"cannot_request_location_accuracy", @"Location permission hasn't been requested first", nil);
Expand Down
8 changes: 8 additions & 0 deletions ios/LocationAlways/RNPermissionHandlerLocationAlways.mm
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ + (NSString * _Nonnull)handlerUniqueId {
}

- (RNPermissionStatus)currentStatus {
#if TARGET_OS_TV
return RNPermissionStatusNotAvailable;
#else
switch ([CLLocationManager authorizationStatus]) {
case kCLAuthorizationStatusNotDetermined:
return RNPermissionStatusNotDetermined;
Expand All @@ -32,10 +35,14 @@ - (RNPermissionStatus)currentStatus {
case kCLAuthorizationStatusAuthorizedAlways:
return RNPermissionStatusAuthorized;
}
#endif
}

- (void)requestWithResolver:(void (^ _Nonnull)(RNPermissionStatus))resolve
rejecter:(void (^ _Nonnull)(NSError * _Nonnull))reject {
#if TARGET_OS_TV
resolve(RNPermissionStatusNotAvailable);
#else
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];

if (status != kCLAuthorizationStatusNotDetermined && status != kCLAuthorizationStatusAuthorizedWhenInUse) {
Expand All @@ -58,6 +65,7 @@ - (void)requestWithResolver:(void (^ _Nonnull)(RNPermissionStatus))resolve
}

[_locationManager requestAlwaysAuthorization];
#endif
}

- (void)onApplicationWillResignActive {
Expand Down
Loading

0 comments on commit ac0eb65

Please sign in to comment.