SwiftUI入门 - 19. webview的交互

置顶

菜鸟入门,各位大佬轻喷,如有谬误之处欢迎讨论建议,也欢迎各位道友与我同行

“不积跬步,无以至千里;不积小流,无以成江海”

继续

上文中我们讨论了webview的基本使用,能展示本地的HTML或者远程的URL。

在日常的开发中,webview肯定是需要跟原生进行交互的,例如获取设备信息,调起摄像头等等HTML中不具备的能力。

所以本章我们来探讨 SwiftUI 与 webview 之间的交互。

思考

SwiftUI 与 webview 之间的交互,可以分为两种:

一种是SwiftUI向webview发送消息,上一篇文章中已经有涉及,直接调用 webview.evaluateJavascript 方法即可

另一种是 webview 主动向 SwiftUI 发送消息,SwiftUI接收到消息后执行操作,执行完毕后再进行上一种方式向 webview 发送消息。

实现

修改 webview.swift 文件

// 这是一个专门用于处理对于webview回传数据的类
class dealMessage:NSObject,WKScriptMessageHandler{
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if message.name == "request" {
            print("接收到消息:\(message.body)")
        }
    }
}
// 制定一个数据模型,这里面有webview的操作句柄
// 后续我们可以把与webview 的交互写到这个类里面
class webviewModel: ObservableObject{
    let webview:WKWebView;
    init() {
        let config = WKWebViewConfiguration();
        let userContent = WKUserContentController();
        // 注入交互处理器,名称为 request
        // 调用方式为 window.webkit.messageHandlers.request.postMessage("okokk")
        userContent.add(dealMessage(), name: "request");
        // 提前注入脚本,这里可以把交互的方法封装好提前注入HTML,以免逻辑侵入到webview中
        // 这个方法可以选择注入的时机,evaluateJavascript 只能在webview初始化之后调用,当然之后再注入也可以
        userContent.addUserScript(WKUserScript(source: "function changeName(){window.webkit.messageHandlers.request.postMessage('okokk')}", injectionTime: .atDocumentStart, forMainFrameOnly: false))
        config.userContentController = userContent;
        // 实例化 WkWebView,带上config
        self.webview = WKWebView(frame: .zero,configuration: config)
        // 加载本地HTML
        // 这个例子加载的是本地 Resource文件夹下的 index.html
         let HTMLSTRING = try! String(contentsOfFile: Bundle.main.path(forResource: "index", ofType: "html")!,encoding: .utf8)
         self.webview.loadHTMLString(HTMLSTRING, baseURL: Bundle.main.resourceURL);
    }
}

实现效果如下:
在这里插入图片描述
接收到了 webview 发出的消息

踩坑

  1. HTML文件不能直接在finder中建文件夹放进去,要把整个文件夹拖入文件树,如图:
    在这里插入图片描述
  2. 此后也只能在这儿改,要么就再文件树里删掉再重新导入
  3. evaluateJavaScript 不能紧跟初始化调用,也不能在初始化之前调用,都是无效的
  4. 需要注入的话要使用 addUserScript

总结

  1. webview 与 SwiftUI 的基本双向交互
  2. 本地HTML资源导入的坑,不能直接在finder 中建立文件夹使用
  3. 注入和执行 script 的区别
  4. 注意这里没有实现 webview 调用 SwiftUI 方法时的返回值,可以提前注入一个接收方法,利用promise的pending原理将发送方法封装之后再进行使用。

欢迎关注gongzhonghao【思跃喵】,一起探讨。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我码玄黄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值