feat(ios): Enhanced permissions handling to prevent repetitive prompts. (#2257)
This commit is contained in:
parent
46ecef868a
commit
cd42aa7f11
|
@ -9,6 +9,14 @@
|
|||
#import <React/RCTDefines.h>
|
||||
#import <WebKit/WebKit.h>
|
||||
|
||||
typedef enum RNCWebViewPermissionGrantType : NSUInteger {
|
||||
RNCWebViewPermissionGrantType_GrantIfSameHost_ElsePrompt,
|
||||
RNCWebViewPermissionGrantType_GrantIfSameHost_ElseDeny,
|
||||
RNCWebViewPermissionGrantType_Deny,
|
||||
RNCWebViewPermissionGrantType_Grant,
|
||||
RNCWebViewPermissionGrantType_Prompt
|
||||
} RNCWebViewPermissionGrantType;
|
||||
|
||||
@class RNCWebView;
|
||||
|
||||
@protocol RNCWebViewDelegate <NSObject>
|
||||
|
@ -84,6 +92,10 @@
|
|||
@property (nonatomic, assign) BOOL limitsNavigationsToAppBoundDomains;
|
||||
#endif
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 /* iOS 15 */
|
||||
@property (nonatomic, assign) RNCWebViewPermissionGrantType mediaCapturePermissionGrantType;
|
||||
#endif
|
||||
|
||||
+ (void)setClientAuthenticationCredential:(nullable NSURLCredential*)credential;
|
||||
+ (void)setCustomCertificatesForHost:(nullable NSDictionary *)certificates;
|
||||
- (void)postMessage:(NSString *_Nullable)message;
|
||||
|
|
|
@ -149,6 +149,7 @@ NSString *const CUSTOM_SELECTOR = @"_CUSTOM_SELECTOR_";
|
|||
_savedAutomaticallyAdjustsScrollIndicatorInsets = NO;
|
||||
#endif
|
||||
_enableApplePay = NO;
|
||||
_mediaCapturePermissionGrantType = RNCWebViewPermissionGrantType_Prompt;
|
||||
}
|
||||
|
||||
#if !TARGET_OS_OSX
|
||||
|
@ -1063,6 +1064,32 @@ NSString *const CUSTOM_SELECTOR = @"_CUSTOM_SELECTOR_";
|
|||
#endif // !TARGET_OS_OSX
|
||||
}
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 /* iOS 15 */
|
||||
/**
|
||||
* Media capture permissions (prevent multiple prompts)
|
||||
*/
|
||||
- (void) webView:(WKWebView *)webView
|
||||
requestMediaCapturePermissionForOrigin:(WKSecurityOrigin *)origin
|
||||
initiatedByFrame:(WKFrameInfo *)frame
|
||||
type:(WKMediaCaptureType)type
|
||||
decisionHandler:(void (^)(WKPermissionDecision decision))decisionHandler {
|
||||
if (_mediaCapturePermissionGrantType == RNCWebViewPermissionGrantType_GrantIfSameHost_ElsePrompt || _mediaCapturePermissionGrantType == RNCWebViewPermissionGrantType_GrantIfSameHost_ElseDeny) {
|
||||
if ([origin.host isEqualToString:webView.URL.host]) {
|
||||
decisionHandler(WKPermissionDecisionGrant);
|
||||
} else {
|
||||
WKPermissionDecision decision = _mediaCapturePermissionGrantType == RNCWebViewPermissionGrantType_GrantIfSameHost_ElsePrompt ? WKPermissionDecisionPrompt : WKPermissionDecisionDeny;
|
||||
decisionHandler(decision);
|
||||
}
|
||||
} else if (_mediaCapturePermissionGrantType == RNCWebViewPermissionGrantType_Deny) {
|
||||
decisionHandler(WKPermissionDecisionDeny);
|
||||
} else if (_mediaCapturePermissionGrantType == RNCWebViewPermissionGrantType_Grant) {
|
||||
decisionHandler(WKPermissionDecisionGrant);
|
||||
} else {
|
||||
decisionHandler(WKPermissionDecisionPrompt);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !TARGET_OS_OSX
|
||||
/**
|
||||
* topViewController
|
||||
|
|
|
@ -22,6 +22,16 @@ RCT_ENUM_CONVERTER(WKContentMode, (@{
|
|||
@"desktop": @(WKContentModeDesktop),
|
||||
}), WKContentModeRecommended, integerValue)
|
||||
#endif
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 /* iOS 15 */
|
||||
RCT_ENUM_CONVERTER(RNCWebViewPermissionGrantType, (@{
|
||||
@"grantIfSameHostElsePrompt": @(RNCWebViewPermissionGrantType_GrantIfSameHost_ElsePrompt),
|
||||
@"grantIfSameHostElseDeny": @(RNCWebViewPermissionGrantType_GrantIfSameHost_ElseDeny),
|
||||
@"deny": @(RNCWebViewPermissionGrantType_Deny),
|
||||
@"grant": @(RNCWebViewPermissionGrantType_Grant),
|
||||
@"prompt": @(RNCWebViewPermissionGrantType_Prompt),
|
||||
}), RNCWebViewPermissionGrantType_Prompt, integerValue)
|
||||
#endif
|
||||
@end
|
||||
|
||||
@implementation RNCWebViewManager
|
||||
|
@ -93,6 +103,10 @@ RCT_EXPORT_VIEW_PROPERTY(contentMode, WKContentMode)
|
|||
RCT_EXPORT_VIEW_PROPERTY(limitsNavigationsToAppBoundDomains, BOOL)
|
||||
#endif
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 /* iOS 15 */
|
||||
RCT_EXPORT_VIEW_PROPERTY(mediaCapturePermissionGrantType, RNCWebViewPermissionGrantType)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Expose methods to enable messaging the webview.
|
||||
*/
|
||||
|
|
|
@ -77,6 +77,7 @@ This document lays out the current public properties and methods for the React N
|
|||
- [`ignoreSilentHardwareSwitch`](Reference.md#ignoreSilentHardwareSwitch)
|
||||
- [`onFileDownload`](Reference.md#onFileDownload)
|
||||
- [`limitsNavigationsToAppBoundDomains`](Reference.md#limitsNavigationsToAppBoundDomains)
|
||||
- [`mediaCapturePermissionGrantType`](Reference.md#mediaCapturePermissionGrantType)
|
||||
- [`autoManageStatusBarEnabled`](Reference.md#autoManageStatusBarEnabled)
|
||||
- [`setSupportMultipleWindows`](Reference.md#setSupportMultipleWindows)
|
||||
- [`basicAuthCredential`](Reference.md#basicAuthCredential)
|
||||
|
@ -1375,6 +1376,32 @@ Example:
|
|||
|
||||
---
|
||||
|
||||
### `mediaCapturePermissionGrantType`
|
||||
|
||||
This property specifies how to handle media capture permission requests. Defaults to `prompt`, resulting in the user being prompted repeatedly. Available on iOS 15 and later.
|
||||
|
||||
Possible values:
|
||||
|
||||
- `grantIfSameHostElsePrompt`: If the security origin's host of the permission request equals the host of the WebView's current URL, the permission is granted if it has been granted before. Otherwise, the user gets prompted.
|
||||
- `grantIfSameHostElseDeny`: If the security origin's host of the permission request equals the host of the WebView's current URL, the permission is granted if it has been granted before. Otherwise, it gets denied.
|
||||
- `deny`
|
||||
- `grant`: The permission is granted if it has been granted before.
|
||||
- `prompt`
|
||||
|
||||
Note that a grant may still result in a prompt, for example if the user has never been prompted for the permission before.
|
||||
|
||||
| Type | Required | Platform |
|
||||
| ------ | -------- | -------- |
|
||||
| string | No | iOS |
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
<WebView mediaCapturePermissionGrantType={'grantIfSameHostElsePrompt'} />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `autoManageStatusBarEnabled`
|
||||
|
||||
If set to `true`, the status bar will be automatically hidden/shown by WebView, specifically when full screen video is being watched. If `false`, WebView will not manage the status bar at all. The default value is `true`.
|
||||
|
|
|
@ -335,6 +335,13 @@ export interface AndroidNativeWebViewProps extends CommonNativeWebViewProps {
|
|||
|
||||
export declare type ContentInsetAdjustmentBehavior = 'automatic' | 'scrollableAxes' | 'never' | 'always';
|
||||
|
||||
export declare type MediaCapturePermissionGrantType =
|
||||
| 'grantIfSameHostElsePrompt'
|
||||
| 'grantIfSameHostElseDeny'
|
||||
| 'deny'
|
||||
| 'grant'
|
||||
| 'prompt';
|
||||
|
||||
export declare type ContentMode = 'recommended' | 'mobile' | 'desktop';
|
||||
|
||||
export interface IOSNativeWebViewProps extends CommonNativeWebViewProps {
|
||||
|
@ -362,6 +369,7 @@ export interface IOSNativeWebViewProps extends CommonNativeWebViewProps {
|
|||
injectedJavaScriptBeforeContentLoadedForMainFrameOnly?: boolean;
|
||||
onFileDownload?: (event: FileDownloadEvent) => void;
|
||||
limitsNavigationsToAppBoundDomains?: boolean;
|
||||
mediaCapturePermissionGrantType?: MediaCapturePermissionGrantType;
|
||||
}
|
||||
|
||||
export interface MacOSNativeWebViewProps extends CommonNativeWebViewProps {
|
||||
|
@ -663,6 +671,13 @@ export interface IOSWebViewProps extends WebViewSharedProps {
|
|||
*/
|
||||
limitsNavigationsToAppBoundDomains?: boolean;
|
||||
|
||||
/**
|
||||
* This property specifies how to handle media capture permission requests.
|
||||
* Defaults to `prompt`, resulting in the user being prompted repeatedly.
|
||||
* Available on iOS 15 and later.
|
||||
*/
|
||||
mediaCapturePermissionGrantType?: MediaCapturePermissionGrantType;
|
||||
|
||||
/**
|
||||
* A Boolean value which, when set to `true`, WebView will be rendered with Apple Pay support.
|
||||
* Once set, websites will be able to invoke apple pay from React Native Webview.
|
||||
|
|
Loading…
Reference in New Issue