美文网首页Mac开发锻炼吃饭的家伙
iOS WKWebView实现blob协议文件下载

iOS WKWebView实现blob协议文件下载

作者: 燃_火 | 来源:发表于2022-05-20 17:28 被阅读0次

WKWebView不支持blob协议文件的下载,使用js注入,让js代码去下载,完成后将数据返回原生。
blob地址样式:blob:http://192.168.4.254:8080/9994c148-85f7-41fe-aa4c-47b5a91f4868
拿图片举例

  1. 配置webview,这里的注册名称"readBlob"需要和前端确定统一,js是通过这个方法名称和webview通信的。
 let configuretion = WKWebViewConfiguration()
 configuretion.preferences.minimumFontSize = 10.0//设置最小字体
 configuretion.preferences.javaScriptEnabled = true//打开js交互
 configuretion.preferences.javaScriptCanOpenWindowsAutomatically = false//在iOS上默认为NO,表示不能自动通过窗口打开
  let userContentController = WKUserContentController()
  userContentController.add(self, name: “readBlob”)
  configuretion.userContentController = userContentController
  1. 注入js代码,这里需要注意的是,需要等待webview加载完成后,才可以注入js代码,否则无效。
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    print("加载完成")
    //下载blob协议文件注入js代码
    if let loadUrl = webView.url?.absoluteString {
        if (loadUrl.contains("blob:")) && (loadUrl.substring(start: 0, 5) == "blob:") {
            let str = "var xhr = new XMLHttpRequest();" +
                      "xhr.open('GET', '\(loadUrl)', true);" +
                      "xhr.responseType = 'blob';" +
                      "xhr.setRequestHeader('Content-type', 'text/plain');" +
                      "xhr.onload = function(e) {" +
                          "if (this.status == 200) {" +
                              "var blob = this.response;" +
                              "var reader = new FileReader();" +
                              "reader.readAsDataURL(blob);" +
                              "reader.onloadend = function() {" +
                                  "window.webkit.messageHandlers.readBlob.postMessage(reader.result);" +
                              "}" +
                          "}" +
                      "};" +
                      "xhr.send();"
            webView.evaluateJavaScript(str, completionHandler: nil)
        }
    } 
}

注意js代码中的"reader.readAsDataURL(blob);"是将blob文件转成base64格式返给webview的。原生需要处理一下,转成图片。

  1. 接收js返回的数据,转成文件。
//获取js下载完成后将base64格式数据传给webview
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if message.name == "readBlob" {
                 //print(message.body)//base64类型
                var base64String = ""
                if let str = message.body as? String {
                    base64String = str.replacingOccurrences(of: " ", with: "")//去除空格
                    base64String = base64String.replacingOccurrences(of: "\r", with: "")//去除回车符
                    base64String = base64String.replacingOccurrences(of: "\n", with: "")//去除换行符
                    //有前缀,例如data:image/png;base64, 则去除(文件格式自行添加)
                    base64String = base64String.replacingOccurrences(of: "data:image/png;base64,", with: "")
                    base64String = base64String.replacingOccurrences(of: "data:image/jpg;base64,", with: "")
                    base64String = base64String.replacingOccurrences(of: "data:image/jpeg;base64,", with: "")
                    base64String = base64String.replacingOccurrences(of: "data:image/gif;base64,", with: "")
                    let base64ImageData = NSData.init(base64Encoded: base64String, options: .ignoreUnknownCharacters)
                    if let imgData = base64ImageData as Data? {
                        let img = UIImage.init(data: imgData)
                        if img != nil {
                            //将图片保存至相册
                            UIImageWriteToSavedPhotosAlbum(img!, nil, nil, nil)
                            print("保存图片成功")
                        }
                    }
                }
        }
}

相关文章

网友评论

    本文标题:iOS WKWebView实现blob协议文件下载

    本文链接:https://www.haomeiwen.com/subject/ofsfprtx.html