You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Given this repos example code, iOS will consistently request camera permissions once per app start (tested on iOS 16.4 Simulator). Looks like there are some ways to mitigate this by following some of the steps in this SO post. I implemented a modified version of it, since we want to preserve the existing functionality of the IOSWebViewManager.WebViewUIDelegate used by BlazorWebView if possible (i.e. alert, prompt, confirm dialogs). Just wanted to share it in case others may find it useful.
Add within CreateMauiApp()
BlazorWebViewHandler.BlazorWebViewMapper.Add("custom",(handler,view)=>{#ifIOS||MACCATALYST// Add custom UIDelegate's so that we can grant permission requests// https://stackoverflow.com/a/75649052/10388359varexistingDelegate= handler.PlatformView.UIDelegate; handler.PlatformView.UIDelegate =new CustomWrapperWebViewDelegate(existingDelegate);#endif});
Add under Platforms\iOS folder
internalstaticclassIWKUIDelegateExtensions{internalstaticvoidGrantDecision(thisIWKUIDelegate_,Action<WKPermissionDecision>decisionHandler){if(OperatingSystem.IsIOSVersionAtLeast(15,0))
decisionHandler(WKPermissionDecision.Grant);}}/// <summary>Used as a wrapper to automatically grant permissions for <see cref="WebView"/>'s using internal implementations of <see cref="WKUIDelegate"/> such as <see cref="BlazorWebView"/> which uses <see cref="IOSWebViewManager.WebViewUIDelegate"/></summary>publicclassCustomWrapperWebViewDelegate:WKUIDelegate{privatereadonlyIWKUIDelegate?existingDelegate;publicCustomWrapperWebViewDelegate(IWKUIDelegate?existingDelegate)=>this.existingDelegate =existingDelegate;publicoverridevoidRequestDeviceOrientationAndMotionPermission(WKWebViewwebView,WKSecurityOriginorigin,WKFrameInfoframe,Action<WKPermissionDecision>decisionHandler)=>this.GrantDecision(decisionHandler);publicoverridevoidRequestMediaCapturePermission(WKWebViewwebView,WKSecurityOriginorigin,WKFrameInfoframe,WKMediaCaptureTypetype,Action<WKPermissionDecision>decisionHandler)=>this.GrantDecision(decisionHandler);publicoverridevoidCommitPreviewingViewController(WKWebViewwebView,UIViewControllerpreviewingViewController)=> existingDelegate?.CommitPreviewingViewController(webView, previewingViewController);publicoverridevoidContextMenuDidEnd(WKWebViewwebView,WKContextMenuElementInfoelementInfo)=> existingDelegate?.ContextMenuDidEnd(webView, elementInfo);publicoverridevoidContextMenuWillPresent(WKWebViewwebView,WKContextMenuElementInfoelementInfo)=> existingDelegate?.ContextMenuWillPresent(webView, elementInfo);publicoverrideWKWebView?CreateWebView(WKWebViewwebView,WKWebViewConfigurationconfiguration,WKNavigationActionnavigationAction,WKWindowFeatureswindowFeatures)=> existingDelegate?.CreateWebView(webView, configuration, navigationAction, windowFeatures);publicoverridevoidDidClose(WKWebViewwebView)=> existingDelegate?.DidClose(webView);publicoverrideUIViewController?GetPreviewingViewController(WKWebViewwebView,WKPreviewElementInfoelementInfo, IWKPreviewActionItem[]previewActions)=> existingDelegate?.GetPreviewingViewController(webView, elementInfo, previewActions);publicoverridevoidRunJavaScriptAlertPanel(WKWebViewwebView,stringmessage,WKFrameInfoframe,ActioncompletionHandler)=> existingDelegate?.RunJavaScriptAlertPanel(webView, message, frame, completionHandler);publicoverridevoidRunJavaScriptConfirmPanel(WKWebViewwebView,stringmessage,WKFrameInfoframe,Action<bool>completionHandler)=> existingDelegate?.RunJavaScriptConfirmPanel(webView, message, frame, completionHandler);publicoverridevoidRunJavaScriptTextInputPanel(WKWebViewwebView,stringprompt,string?defaultText,WKFrameInfoframe,Action<string>completionHandler)=> existingDelegate?.RunJavaScriptTextInputPanel(webView, prompt, defaultText, frame, completionHandler);publicoverridevoidSetContextMenuConfiguration(WKWebViewwebView,WKContextMenuElementInfoelementInfo,Action<UIContextMenuConfiguration>completionHandler)=> existingDelegate?.SetContextMenuConfiguration(webView, elementInfo, completionHandler);publicoverrideboolShouldPreviewElement(WKWebViewwebView,WKPreviewElementInfoelementInfo)=>(bool)(existingDelegate?.ShouldPreviewElement(webView, elementInfo));publicoverridevoidShowLockDownMode(WKWebViewwebView,stringfirstUseMessage,Action<WKDialogResult>completionHandler)=> existingDelegate?.ShowLockDownMode(webView, firstUseMessage, completionHandler);publicoverridevoidWillCommitContextMenu(WKWebViewwebView,WKContextMenuElementInfoelementInfo,IUIContextMenuInteractionCommitAnimatinganimator)=> existingDelegate?.WillCommitContextMenu(webView, elementInfo, animator);}
Interestingly, for me it doesn't even prompt to allow camera access at all, just allows it w/o prompt, however I haven't tested outside of a simulator or iOS 16.4 yet.
For those of you interested, if you're working with just the default MAUI WebView, we can take a similar approach:
Add within CreateMauiApp()
WebViewHandler.Mapper.AppendToMapping(nameof(WKUIDelegate),(handler,view)=>{#ifIOS||MACCATALYST// Add custom UIDelegate's so that we can grant permission requests// https://stackoverflow.com/a/75649052/10388359if(existingDelegate is MauiWebViewUIDelegate d) handler.PlatformView.UIDelegate =new CustomMauiWebViewUIDelegate(handler);#endif});
Add under Platforms\iOS folder
/// <summary>Used to automatically grant permissions for <see cref="WebView"/>'s using <see cref="MauiWebViewUIDelegate"/></summary>publicclassCustomMauiWebViewUIDelegate:MauiWebViewUIDelegate{publicCustomMauiWebViewUIDelegate(IWebViewHandlerhandler):base(handler){}publicoverridevoidRequestMediaCapturePermission(WKWebViewwebView,WKSecurityOriginorigin,WKFrameInfoframe,WKMediaCaptureTypetype,Action<WKPermissionDecision>decisionHandler)=>this.GrantDecision(decisionHandler);}
And just one extra tidbit, if working with the MAUI WebView, you'll need to enable some WKWebViewConfiguration options (primarily AllowsInlineMediaPlayback & MediaTypesRequiringUserActionForPlayback), which will be enabled by default in net8.0, however you can enable them in net7.0 by following the example in this PR (which is what added these options to be default for next version). These same options can be configured for the BlazorWebView within the BlazorWebViewInitializing event, which this example repo already covers:
Given this repos example code, iOS will consistently request camera permissions once per app start (tested on iOS 16.4 Simulator). Looks like there are some ways to mitigate this by following some of the steps in this SO post. I implemented a modified version of it, since we want to preserve the existing functionality of the
IOSWebViewManager.WebViewUIDelegate
used byBlazorWebView
if possible (i.e.alert
,prompt
,confirm
dialogs). Just wanted to share it in case others may find it useful.CreateMauiApp()
Platforms\iOS
folderInterestingly, for me it doesn't even prompt to allow camera access at all, just allows it w/o prompt, however I haven't tested outside of a simulator or iOS 16.4 yet.
For those of you interested, if you're working with just the default MAUI
WebView
, we can take a similar approach:CreateMauiApp()
Platforms\iOS
folderAnd just one extra tidbit, if working with the MAUI
WebView
, you'll need to enable someWKWebViewConfiguration
options (primarilyAllowsInlineMediaPlayback
&MediaTypesRequiringUserActionForPlayback
), which will be enabled by default innet8.0
, however you can enable them innet7.0
by following the example in this PR (which is what added these options to be default for next version). These same options can be configured for theBlazorWebView
within theBlazorWebViewInitializing
event, which this example repo already covers:MauiBlazorPermissionsExample/MauiBlazorPermissionsExample/MainPage.xaml.iOS.cs
Lines 11 to 15 in 1fca91e
What a rabbit hole... Hope someone finds this useful!
The text was updated successfully, but these errors were encountered: