【问题标题】:Setting local image on WKWebview using evaluateJavascript method使用 evaluateJavascript 方法在 WKWebview 上设置本地图像
【发布时间】:2020-11-21 06:03:55
【问题描述】:

我有一个 HTML 文件,其内容中包含本地资源文件,例如 css、js 文件。这些本地资源文件为 zip 格式。我的应用程序使用 WKWebView 来显示这个 html 文件。我正在尝试在本地保存的 WKWebview 上的 html 图像元素之一中上传图像,并且 html 不会随图像更新。我在本地 html 中有一个像这样的 html 图像标签。

<img id='image' style='display: block; height: 100%; width:100%; margin:0 auto;' />

并且在这个图片标签中加载的这个图片是在WKWebview中加载本地html文件后生成的。生成图像后,我正在尝试使用像这样的评估 javascript 方法更新图像标签。

NSString *js = @"document.getElementById('image').src='document directory/Library/images/generatedImage.png';"
[self.wkWebView evaluateJavaScript:js completionHandler:nil];

我在这里做错了吗?我还读到我们无法在本地更新 2 年前的图像,还是一样吗?我的场景是否有任何解决方法。提前致谢。

【问题讨论】:

标签: ios objective-c swift ipad wkwebview


【解决方案1】:

我可以想出两种方法来做你想做的事。

  1. 自定义 URL 方案
  2. 将图像转换为 base64,然后通过评估 Javascript 进行设置

自定义网址方案

iOS 版本 11 支持此功能,如果您支持低于 11 的版本,那么您最好使用第二种方法。基本思想是使用自定义协议(如 my-scheme://your-path)提及您的 URL,然后拦截该路径并提供对 WKWebView 的响应。在这种情况下,您必须创建一个扩展 WKSchemeHandler 的类并覆盖它所需的方法。例如

import WebKit
import Foundation
class CustomeSchemeHandler : NSObject,WKURLSchemeHandler {
    func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
       
        
    }

    func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {
       
    }
}

在 start 方法中,您可以从所需的来源加载内容,然后通过返回响应

urlSchemeTask.didReceive(response)
urlSchemeTask.didReceive(data)
urlSchemeTask.didFinish()

实现逻辑后,需要通过setURLSchemeHandler(_:forURLScheme:)向WKWebView注册

看到上述内容后,您可以在自定义方案中提及图像 URL,并将工作留给您的 CustomSchemeHandler。

这种方法非常成熟,从长远来看确实很有帮助。我找到了一篇非常好的简短文章,详细介绍了实现,请查看:https://medium.com/@kumarreddy_b/custom-scheme-handling-in-uiwebview-wkwebview-bbeb2f3f6cc1

将图像转换为 base64,然后通过评估 Javascript 进行设置

  1. 从您的路径创建 UIImage,例如https://stackoverflow.com/a/43006566/2299040
  2. 将图片转换为base64
  3. 获取您的 HTML 图像元素的 ID 并加载 base64 字符串

例如

if let image = UIImage(contentsOfFile: ""){
    //Now use image to create into NSData format
    if let imageData = image.jpegData(compressionQuality: 0.8){
        let strBase64 = imageData.base64EncodedString(options: .lineLength64Characters)
        webView.evaluateJavaScript("document.getElementById('your-image-element-id').setAttribute('src', '\(strBase64)');")
    }
}

【讨论】:

  • 我使用了第二种方法。将图像转换为 Base64,然后通过 javascript 添加。感谢您的帮助。
  • 它在 iOS14 上停止工作。于是,想到了实现 WKURLSchemeHandler。代理在 webview 加载时被调用,但是当我尝试使用评估 javascript 添加图像标签的源时,它不会被调用。
【解决方案2】:

对于您的示例,我可以通过将该 URL 设置为 src 从 Internet 加载图像。

我猜你可能在加载 webview 时没有授予对本地图像文件目录的读取权限。

利用 wkwebview 的 loadFileURL 方法通过授予对特定目录的访问权限来加载 HTML 文件

对于 EG(在 Swift 中),

let imgDir = "<your image directory>"
let imgDirUrl = URL(fileURLWithPath: String(format: "%@", imgDir), isDirectory: true)
webView.loadFileURL(<your HTML file URL path>, allowingReadAccessTo: imgDirUrl)

(在 objc 中)

NSString *imgDir = "<your image directory>"
NSURL *imgDirUrl = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@",imgDir] isDirectory:true];
[webView loadFileURL:<your HTML file URL path> allowingReadAccessToURL:imgDirUrl];

【讨论】:

  • 图像是动态创建的,并保存在 html 文件 url 路径以外的不同路径中。有没有其他方法可以在 html 上使用 javascript 更新图像?
  • 您可以尝试授予整个文档目录的读取权限吗?在这种情况下,可以在创建图像的任何位置访问图像
  • html 是通过 Cordova WebviewEngine 加载的,我尝试在他们的 WKConfiguration 首选项中授予对文件夹的访问权限,但它似乎不起作用。
  • 你能分享你加载webview的代码吗?
猜你喜欢
  • 1970-01-01
  • 2018-02-05
  • 1970-01-01
  • 2022-11-17
  • 2022-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多