fix(ios): auto-grant WKWebView media capture permission - #635
Conversation
Matches Capacitor core's WebViewDelegationHandler behavior and the plugin's existing geolocation handling. Without this delegate method, WebKit shows its own per-origin camera/microphone prompt on top of the iOS system permission prompt, and because the grant is not persisted across app launches (WebKit bug 220416) users are re-prompted on every cold start of the host app. The OS-level permission (Info.plist usage descriptions + system prompt) still fully applies.
Beta npm buildThis PR comes from a fork, so beta publish is disabled for security. If you need a beta package, move the branch into this repository first. |
📝 WalkthroughWalkthrough
ChangesiOS media capture permissions
Estimated code review effort: 1 (Trivial) | ~2 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@ios/Sources/InAppBrowserPlugin/WKWebViewController.swift`:
- Line 3354: Update the
webView(_:requestMediaCapturePermissionFor:initiatedByFrame:type:decisionHandler:)
delegate signature to replace the unused webView, frame, and type bindings with
underscores while preserving the required external labels and types.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: d1fdc887-9ed9-4d1c-b22b-1569ae8b8ae9
📒 Files selected for processing (1)
ios/Sources/InAppBrowserPlugin/WKWebViewController.swift
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
Cap-go/capacitor-updater(manual)
| } | ||
|
|
||
| @available(iOS 15.0, *) | ||
| public func webView(_ webView: WKWebView, requestMediaCapturePermissionFor origin: WKSecurityOrigin, initiatedByFrame frame: WKFrameInfo, type: WKMediaCaptureType, decisionHandler: @escaping (WKPermissionDecision) -> Void) { |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Mark unused delegate parameters explicitly.
webView, frame, and type are unused and trigger the three reported SonarCloud warnings. Preserve the required delegate labels while replacing their local bindings with _ (for example, webView(_: WKWebView, ... initiatedByFrame _: WKFrameInfo, type _: WKMediaCaptureType)).
🧰 Tools
🪛 GitHub Check: SonarCloud Code Analysis
[warning] 3354-3354: Remove the unused function parameter "frame" or name it "_".
[warning] 3354-3354: Remove the unused function parameter "type" or name it "_".
[warning] 3354-3354: Remove the unused function parameter "webView" or name it "_".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@ios/Sources/InAppBrowserPlugin/WKWebViewController.swift` at line 3354,
Update the
webView(_:requestMediaCapturePermissionFor:initiatedByFrame:type:decisionHandler:)
delegate signature to replace the unused webView, frame, and type bindings with
underscores while preserving the required external labels and types.
Source: Linters/SAST tools
There was a problem hiding this comment.
1 issue found across 1 file
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="ios/Sources/InAppBrowserPlugin/WKWebViewController.swift">
<violation number="1" location="ios/Sources/InAppBrowserPlugin/WKWebViewController.swift:3363">
P1: Any HTTP(S) origin reached through navigation or redirect can receive camera/microphone access without WebKit's origin prompt once the host app has OS permission. Unlike Capacitor's trusted app WebView, this browser accepts arbitrary remote pages, so auto-granting should be restricted to an explicit trusted-origin policy and otherwise return `.prompt` or `.deny`.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
| // suppresses WebKit's extra per-origin prompt, which is not persisted | ||
| // across app launches (WebKit bug 220416) and would otherwise re-prompt | ||
| // users on every cold start. | ||
| decisionHandler(.grant) |
There was a problem hiding this comment.
P1: Any HTTP(S) origin reached through navigation or redirect can receive camera/microphone access without WebKit's origin prompt once the host app has OS permission. Unlike Capacitor's trusted app WebView, this browser accepts arbitrary remote pages, so auto-granting should be restricted to an explicit trusted-origin policy and otherwise return .prompt or .deny.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At ios/Sources/InAppBrowserPlugin/WKWebViewController.swift, line 3363:
<comment>Any HTTP(S) origin reached through navigation or redirect can receive camera/microphone access without WebKit's origin prompt once the host app has OS permission. Unlike Capacitor's trusted app WebView, this browser accepts arbitrary remote pages, so auto-granting should be restricted to an explicit trusted-origin policy and otherwise return `.prompt` or `.deny`.</comment>
<file context>
@@ -3349,6 +3349,19 @@ extension WKWebViewController: WKUIDelegate {
+ // suppresses WebKit's extra per-origin prompt, which is not persisted
+ // across app launches (WebKit bug 220416) and would otherwise re-prompt
+ // users on every cold start.
+ decisionHandler(.grant)
+ }
}
</file context>
|
hey @jadamspiers can you check comments and resolve them? |



What
Implements
webView(_:requestMediaCapturePermissionFor:initiatedByFrame:type:decisionHandler:)(iOS 15+) on the
WKUIDelegateinWKWebViewController, auto-granting media capture the sameway the plugin already auto-grants geolocation.
Why
When a page opened with
openWebViewcallsgetUserMedia(microphone/camera):That second prompt is not persisted across app launches for WKWebView
(WebKit bug 220416), so users are re-prompted
every cold start of the host app. For apps embedding a voice/WebRTC experience this breaks the UX.
decisionHandler(.grant)defers entirely to the OS-level permission: if the app doesn't havemicrophone/camera permission, capture still fails and the system prompt still governs access.
This is exactly what Capacitor core does in its own
WebViewDelegationHandler(capacitor/ios WebViewDelegationHandler.swift),
so pages running inside the InAppBrowser WebView now behave like pages in the main Capacitor WebView.
Platform parity
onPermissionRequestinWebViewDialog.java— iOS was the gap.requestGeolocationPermissionFor); this mirrors that handler, including the log line style.Testing
Running in production inside a Capacitor 8 conference app (via
patch-package) that embeds aWebRTC push-to-talk web app: with the patch, the mic prompt appears exactly once (system prompt);
without it, WebKit re-prompts on every app relaunch.
Summary by CodeRabbit