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

更多方法交流可以家魏鑫: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;
    }

其中: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()
                    }
                }
            }
        }
}

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 {
//                 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,针对您的问题,以下是一个解决方案的实例,供参考: 1. 首先,在html中定义一个select标签,并给它一个类名,例如“select-style”: ```html <select class="select-style"> <option value="option1">Option 1</option> <option value="option2">Option 2</option> <option value="option3">Option 3</option> </select> ``` 2. 然后,在CSS中定义该类名的样式,包括一些兼容性的处理: ```css .select-style { -webkit-appearance: none; /* 去掉ios默认样式 */ -moz-appearance: none; /* 去掉firefox默认样式 */ appearance: none; /* 去掉其他浏览器默认样式 */ background-image: url('path/to/arrow-icon'); /* 添加自定义的下拉箭头图标 */ background-size: 12px; /* 设置图标大小 */ background-repeat: no-repeat; /* 不重复显示图标 */ background-position: 95% center; /* 将图标放置在下拉框的右侧中间位置 */ padding: 8px; /* 设置内边距 */ border: 1px solid #ccc; /* 设置边框 */ } ``` 3. 最后,使用JavaScript监听下拉框的变化,并动态修改其选中项的样式: ```javascript var select = document.querySelector('.select-style'); select.addEventListener('change', function() { var selectedOption = this.options[this.selectedIndex]; selectedOption.style.backgroundColor = '#ccc'; selectedOption.style.color = '#fff'; }); ``` 以上就是一个简单的解决方案,它可以使下拉框在ios中显示正常,同时也可以在其他浏览器中兼容。需要注意的是,不同的页面可能需要根据自己的实际情况进行一些微调,例如调整箭头图标的位置和大小等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值