Swift开发iOS应用:如何在WKWebView/WebView中实现麦克风访问?
Hey Eric, let's figure out why your microphone access isn't working with UIWebView and fix this properly. The core issue here is that you're using a deprecated web view component, plus a few missing configurations that are blocking the H5 page from accessing the mic. Let's break this down step by step:
UIWebView was deprecated back in iOS 12, and it has terrible support for modern Web APIs like getUserMedia (the API your H5 page uses to access the microphone). WKWebView is Apple's recommended replacement, and it handles media permissions correctly. This is the first thing you need to change.
Even if you request permission in code, iOS requires you to explain why you need the microphone in your Info.plist. Add these keys (right-click Info.plist > Open As > Source Code to edit):
<key>NSMicrophoneUsageDescription</key> <string>需要访问麦克风以进行录音功能</string> <!-- Replace with your own user-facing explanation -->
Without this, iOS will silently deny the permission request, even if the user taps "Allow".
You need to set up WKWebView's configuration to allow media capture. Here's a complete, updated version of your view controller code:
import UIKit import WebKit class MainViewController: UIViewController, WKUIDelegate, WKNavigationDelegate { var webView: WKWebView! let audioSession = AVAudioSession.sharedInstance() override func viewDidLoad() { super.viewDidLoad() // Request mic permission first requestMicrophonePermission() // Set up WKWebView configuration let webConfig = WKWebViewConfiguration() webConfig.allowsInlineMediaPlayback = true // Useful if your H5 plays media inline // For iOS 14+, explicitly allow media capture permissions if #available(iOS 14.0, *) { webConfig.mediaCapturePermissionsPolicy = .grant } // Initialize and add WKWebView to the view webView = WKWebView(frame: view.bounds, configuration: webConfig) webView.uiDelegate = self webView.navigationDelegate = self view.addSubview(webView) // Load your H5 page guard let url = URL(string: "https://www.somewebsite.com/") else { return } webView.load(URLRequest(url: url)) } private func requestMicrophonePermission() { audioSession.requestRecordPermission { [weak self] granted in DispatchQueue.main.async { guard let self = self else { return } if granted { print("Mic permission granted") do { try self.audioSession.setCategory(.playAndRecord, mode: .default) try self.audioSession.setActive(true) } catch { print("Failed to configure audio session: \(error.localizedDescription)") } } else { print("Mic permission denied") // Optional: Show an alert asking the user to enable permission in Settings } } } } // For iOS 15+, handle granular media capture requests from the web page @available(iOS 15.0, *) func webView(_ webView: WKWebView, requestMediaCapturePermissionFor origin: WKSecurityOrigin, initiatedByFrame frame: WKFrameInfo, type: WKMediaCaptureType, decisionHandler: @escaping (WKPermissionDecision) -> Void) { // You can add logic here to restrict access to specific domains if needed decisionHandler(.grant) } }
Make sure your H5 page is correctly requesting microphone access using the standard Web API:
navigator.mediaDevices.getUserMedia({ audio: true }) .then(stream => { // Use the audio stream for recording console.log("Microphone access granted"); }) .catch(error => { console.error("Error accessing microphone: ", error); });
Avoid using deprecated getUserMedia syntax (like the pre-promise version) as this might not work with WKWebView.
- Always test on a physical device: The iOS Simulator has limited support for microphone access, so you'll need an actual iOS device to verify this works.
- If the user denies permission initially, you can direct them to Settings > [Your App] > Microphone to enable it later.
内容的提问来源于stack exchange,提问作者Eric

