当前位置:   article > 正文

iOS Swift H5 WKWebView交互麦克风录音完访问本地文件路径遇到的问题及解决方案_webview调用h5页面麦克风

webview调用h5页面麦克风

更多方法交流可以家魏鑫:lixiaowu1129,一起探讨iOS相关技术!

需求分析:

最近项目需求需要麦克风录音权限,因为整体上的UI界面是前端wkwebview搭建的,实现功能逻辑是由iOS实现,没有用原生!然后就出现了需要麦克风录音机跟H5交互的功能模块!

查了资料都文章说iOS对h5交互麦克风录音不友好
现在具体工作流程步骤如下:

  1. 首先创建了一个wkwebview
//加载webview视图
    override func loadView() {
        let preference = WKPreferences()
        preference.minimumFontSize = 0
        preference.javaScriptEnabled = true
        preference.javaScriptCanOpenWindowsAutomatically = true
        preference.setValue("TRUE", forKey: "allowFileAccessFromFileURLs")
        debugPrint("这里已经进来了")
        
        // swift 提供给 h5 调用方法
        let userContentController = WKUserContentController()
        userContentController.add(self, name: "callAudio")  //调起iOS音频权限
        userContentController.add(self, name: "recorderStart")  //开始录音
        userContentController.add(self, name: "recorderStop")  //停止录音
        
        let conf = WKWebViewConfiguration()
        conf.userContentController = userContentController
        conf.preferences = preference
        
//        let conf = WKWebViewConfiguration();
//        conf.userContentController.add(self, name: "callAudio")  //调起iOS音频权限
//        conf.userContentController.add(self, name: "recorderStart")  //开始录音
//        conf.userContentController.add(self, name: "recorderStop")  //停止录音
        webView = WKWebView(frame: CGRect(x:0, y:0, width:SCREEN_WIDTH, height:SCREEN_HEIGHT), configuration: conf)
        webView.navigationDelegate = self;
        webView.scrollView.isScrollEnabled = false  //禁止webview滑动滚动
        if #available(iOS 11.0, *) {
            webView.scrollView.contentInsetAdjustmentBehavior = .never;
        }
        view = webView;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

其中:callAudio、recorderStart、recorderStop是iOS跟webview定义好协议接收的方法
2. **重点:**加载完成后接收H5调用的协议方法:

// 接受 h5 调用
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        guard let name = message.value(forKey: "name") as? String, let body = message.value(forKey: "body") as? String  else { return }
        debugPrint("测试链接8888+:\(name)")
        if name == "callAudio" {
            SystemAuth.authMicrophone { result in
                if result{
                    self.webView.evaluateJavaScript("getPermission('\(result)')", completionHandler: nil)
                }else{
                    DispatchQueue.main.async {
                        let alertView = UIAlertView(title: "无法访问您的麦克风" , message: "请到设置 -> 隐私 -> 麦克风 ,打开访问权限", delegate: nil, cancelButtonTitle: "取消", otherButtonTitles: "好的")
                        alertView.show()
                    }
                }
            }
        }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

SystemAuth.authMicrophone 调用录音麦克风权限返回true跟false
self.webView.evaluateJavaScript(“getPermission(’(result)’)”, completionHandler: nil) iOS拦截到方法注入新方法getPermission()携带参数true或者false返回给H5接收

Swift开启iOS的录音权限包括其他照相机权限的代码文件

我整理好在下面的代码了

SystemAuth.Swift

//
//  SystemAuth.swift
//  Authorization
//
//  Created by 柯南 on 2020/9/4.
//  Copyright © 2020 LTM. All rights reserved.
//

import UIKit

/// 媒体资料库/Apple Music
import MediaPlayer
import Photos
import UserNotifications
import Contacts
/// Siri权限
import Intents
/// 语音转文字权限
import Speech
/// 日历、提醒事项
import EventKit
/// Face、TouchID
import LocalAuthentication
import HealthKit
import HomeKit
/// 运动与健身权限
import CoreMotion
/// 防止获取无效 计步器
private let cmPedometer = CMPedometer()

typealias AuthClouser = ((Bool)->())

/// 定义私有全局变量,解决在iOS 13 定位权限弹框自动消失的问题
private let locationAuthManager = CLLocationManager()

/**
 escaping 逃逸闭包的生命周期:
 
 1,闭包作为参数传递给函数;
 
 2,退出函数;
 
 3,闭包被调用,闭包生命周期结束
 即逃逸闭包的生命周期长于函数,函数退出的时候,逃逸闭包的引用仍被其他对象持有,不会在函数结束时释放
 经常使用逃逸闭包的2个场景:
 异步调用: 如果需要调度队列中异步调用闭包,比如网络请求成功的回调和失败的回调,这个队列会持有闭包的引用,至于什么时候调用闭包,或闭包什么时候运行结束都是不确定,上边的例子。
 存储: 需要存储闭包作为属性,全局变量或其他类型做稍后使用,例子待补充
 */
public class SystemAuth {
    
//    /**
//     媒体资料库/Apple Music权限
//
//     - parameters: action 权限结果闭包
//     */
//    class func authMediaPlayerService(clouser :@escaping AuthClouser) {
//        let authStatus = MPMediaLibrary.authorizationStatus()
//        switch authStatus {
//        /// 未作出选择
//        case .notDetermined:
//            MPMediaLibrary.requestAuthorization { (status) in
//                if status == .authorized{
//                    DispatchQueue.main.async {
//                        clouser(true)
//                    }
//                }else{
//                    DispatchQueue.main.async {
//                 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/175225
推荐阅读
相关标签
  

闽ICP备14008679号