An interface for permissions modules that provides standardized permission status types and platform-specific native interfaces for React Native and Expo applications
npx @tessl/cli install tessl/npm-unimodules-permissions-interface@6.2.0The unimodules-permissions-interface package provides a standardized interface for handling permissions across React Native and Expo applications. It defines TypeScript types and enums for permission status management, and provides native platform interfaces for iOS and Android implementations to ensure consistent permission handling across platforms.
npm install unimodules-permissions-interfaceimport { PermissionStatus, PermissionResponse, PermissionExpiration } from "unimodules-permissions-interface";For CommonJS:
const { PermissionStatus, PermissionResponse, PermissionExpiration } = require("unimodules-permissions-interface");import { PermissionStatus, PermissionResponse } from "unimodules-permissions-interface";
// Example permission response
const permissionResponse: PermissionResponse = {
status: PermissionStatus.GRANTED,
expires: "never",
granted: true,
canAskAgain: false
};
// Check permission status
if (permissionResponse.status === PermissionStatus.GRANTED) {
console.log("Permission granted");
} else if (permissionResponse.status === PermissionStatus.DENIED) {
console.log("Permission denied");
} else {
console.log("Permission undetermined");
}Defines standardized permission states for cross-platform consistency.
enum PermissionStatus {
GRANTED = 'granted',
UNDETERMINED = 'undetermined',
DENIED = 'denied',
}The PermissionStatus enum provides three possible states:
GRANTED: Permission has been explicitly granted by the userUNDETERMINED: Permission has not been requested yet or status is unknownDENIED: Permission has been explicitly denied by the userStandardized response object for permission requests across platforms.
interface PermissionResponse {
status: PermissionStatus;
expires: PermissionExpiration;
granted: boolean;
canAskAgain: boolean;
}Properties:
status: Current permission status using PermissionStatus enumexpires: When the permission expires (either 'never' or timestamp)granted: Boolean indicating if permission is currently grantedcanAskAgain: Boolean indicating if the user can be prompted againDefines when a permission expires.
type PermissionExpiration = 'never' | number;Values:
'never': Permission does not expirenumber: Unix timestamp when permission expiresThis package provides native interfaces for platform-specific implementations. These are typically used by native modules and not directly by JavaScript/TypeScript code.
The Android interface provides methods for permission management:
public interface Permissions {
// Get permission status asynchronously
void getPermissionsWithPromise(final Promise promise, String... permissions);
// Request permissions asynchronously
void askForPermissionsWithPromise(final Promise promise, String... permissions);
// Get permission status with callback
void getPermissions(final PermissionsResponseListener response, String... permissions);
// Request permissions with callback
void askForPermissions(final PermissionsResponseListener response, String... permissions);
// Check if permissions are granted (synchronous)
boolean hasGrantedPermissions(String... permissions);
// Check if permission is declared in AndroidManifest
boolean isPermissionPresentInManifest(String permission);
}Static Helper Methods:
// Helper to get permissions with null checking
static void getPermissionsWithPermissionsManager(
Permissions permissionsManager,
final Promise promise,
String... permissions
);
// Helper to request permissions with null checking
static void askForPermissionsWithPermissionsManager(
Permissions permissionsManager,
final Promise promise,
String... permissions
);public enum PermissionsStatus {
GRANTED("granted"),
UNDETERMINED("undetermined"),
DENIED("denied");
public String getStatus();
}@FunctionalInterface
public interface PermissionsResponseListener {
void onResult(Map<String, PermissionsResponse> result);
}data class PermissionsResponse(
val status: PermissionsStatus,
val canAskAgain: Boolean = true
)Constants available:
STATUS_KEY = "status"GRANTED_KEY = "granted"EXPIRES_KEY = "expires"CAN_ASK_AGAIN_KEY = "canAskAgain"SCOPE_KEY = "scope"PERMISSION_EXPIRES_NEVER = "never"SCOPE_IN_USE = "whenInUse"SCOPE_ALWAYS = "always"SCOPE_NONE = "none"The iOS interface provides protocols for permission management:
// Permission status enum
typedef enum UMPermissionStatus {
UMPermissionStatusDenied,
UMPermissionStatusGranted,
UMPermissionStatusUndetermined,
} UMPermissionStatus;
// Protocol for permission requesters
@protocol UMPermissionsRequester <NSObject>
+ (NSString *)permissionType;
- (void)requestPermissionsWithResolver:(UMPromiseResolveBlock)resolve
rejecter:(UMPromiseRejectBlock)reject;
- (NSDictionary *)getPermissions;
@end
// Main permissions interface
@protocol UMPermissionsInterface
- (void)registerRequesters:(NSArray<id<UMPermissionsRequester>> *)newRequesters;
- (void)getPermissionUsingRequesterClass:(Class)requesterClass
resolve:(UMPromiseResolveBlock)resolve
reject:(UMPromiseRejectBlock)reject;
- (BOOL)hasGrantedPermissionUsingRequesterClass:(Class)requesterClass;
- (void)askForPermissionUsingRequesterClass:(Class)requesterClass
resolve:(UMPromiseResolveBlock)resolve
reject:(UMPromiseRejectBlock)reject;
- (id<UMPermissionsRequester>)getPermissionRequesterForType:(NSString *)type;
@end@interface UMPermissionsMethodsDelegate : NSObject
+ (void)getPermissionWithPermissionsManager:(id<UMPermissionsInterface>)permissionsManager
withRequester:(Class)requesterClass
resolve:(UMPromiseResolveBlock)resolve
reject:(UMPromiseRejectBlock)reject;
+ (void)askForPermissionWithPermissionsManager:(id<UMPermissionsInterface>)permissionsManager
withRequester:(Class)requesterClass
resolve:(UMPromiseResolveBlock)resolve
reject:(UMPromiseRejectBlock)reject;
+ (void)registerRequesters:(NSArray<id<UMPermissionsRequester>> *)newRequesters
withPermissionsManager:(id<UMPermissionsInterface>)permissionsManager;
@end@protocol UMUserNotificationCenterProxyInterface <NSObject>
- (void)getNotificationSettingsWithCompletionHandler:(nonnull void(^)(UNNotificationSettings *__nonnull settings))completionHandler;
- (void)requestAuthorizationWithOptions:(UNAuthorizationOptions)options
completionHandler:(nonnull void (^)(BOOL granted, NSError *__nullable error))completionHandler;
@endThis package serves as an interface specification - it defines the contracts that concrete permission implementations must follow. Native modules implementing specific permissions (camera, location, notifications, etc.) should extend these interfaces to provide actual permission handling functionality.
The TypeScript types ensure consistent JavaScript API across all permission modules, while the native interfaces ensure consistent platform-specific implementations. This architecture allows Expo and React Native applications to handle permissions uniformly regardless of the specific permission type or platform.