使用WebViewJavascriptBridge与UIWebView交互

简介:

使用WebViewJavascriptBridge与UIWebView交互

https://github.com/marcuswestin/WebViewJavascriptBridge

 

核心的地方:

UIWebView在加载完网页之后,通过方法stringByEvaluatingJavaScriptFromString:来让这个webView执行js脚本,之后想干啥干啥.

注意:必须是加载完之后!

 

使用

下载源码拖入工程.

使用一个本地的html文件.

<!doctype html>
<html><head>
    <style type='text/css'>
        html { font-family:Helvetica; color:#222; }
        h1 { color:steelblue; font-size:24px; margin-top:24px; }
        button { margin:0 3px 10px; font-size:12px; }
        .logLine { border-bottom:1px solid #ccc; padding:4px 2px; font-family:courier; font-size:11px; }
    </style>
</head><body>
    <h1>WebViewJavascriptBridge Demo</h1>
    
    
    <!--脚本开始的地方-->
    <script>
    window.onerror = function(err) {
        log('window.onerror: ' + err)
    }
    
    <!--申明方法-->
    function connectWebViewJavascriptBridge(callback) {
        if (window.WebViewJavascriptBridge) {
            callback(WebViewJavascriptBridge)
        } else {
            document.addEventListener('WebViewJavascriptBridgeReady', function() {
                callback(WebViewJavascriptBridge)
            }, false)
        }
    }
    
    <!--激活方法-->
    connectWebViewJavascriptBridge(function(bridge) {
        var uniqueId = 1
        function log(message, data) {
            var log = document.getElementById('log')
            var el = document.createElement('div')
            el.className = 'logLine'
            el.innerHTML = uniqueId++ + '. ' + message + (data ? ':<br/>' + JSON.stringify(data) : '')
            if (log.children.length) { log.insertBefore(el, log.children[0]) }
            else { log.appendChild(el) }
        }
        bridge.init(function(message, responseCallback) {
            log('JS got a message', message)
            var data = { 'Javascript Responds':'Wee!' }
            log('JS responding with', data)
            responseCallback(data)
        })

        bridge.registerHandler('testJavascriptHandler', function(data, responseCallback) {
            log('ObjC called testJavascriptHandler with', data)
            var responseData = { 'Javascript Says':'Right back atcha!' }
            log('JS responding with', responseData)
            responseCallback(responseData)
        })

        <!--创建一个按钮-->
        var button = document.getElementById('buttons').appendChild(document.createElement('button'))
        button.innerHTML = 'Send message to ObjC'
        button.onclick = function(e) {
            e.preventDefault()
                                   
            <!--此处是你传参数的地方-->
            var data = 'YouXianMing'
            log('JS sending message', data)
            bridge.send(data, function(responseData) {
                log('JS got response', responseData)
            })
        }

        document.body.appendChild(document.createElement('br'))
    })
    
    <!--脚本结束的地方-->
    </script>
    <div id='buttons'></div> <div id='log'></div>
</body></html>

RootViewController代码如下:
//
//  RootViewController.m
//  WebViewJavascriptBridge
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "RootViewController.h"
#import "WebViewJavascriptBridge.h"

@interface RootViewController ()<UIWebViewDelegate>

@property (nonatomic, strong) UIWebView                *webView;
@property (nonatomic, strong) WebViewJavascriptBridge  *bridge;

@end

#define BUNDLE_FILE(fileName)  [[NSBundle mainBundle] pathForResource:fileName ofType:nil];
#define HTML_STRING(htmlPath)  [NSString stringWithContentsOfFile:htmlPath \
encoding:NSUTF8StringEncoding error:nil]
#define FILE_URL(path)         [NSURL fileURLWithPath:path]

@implementation RootViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // 获取本地html文件
    NSString *htmlPath = BUNDLE_FILE(@"demo.html");

    // 初始化UIWebView并添加进view中
    _webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
    [_webView loadHTMLString:HTML_STRING(htmlPath)
                     baseURL:FILE_URL(htmlPath)];
    [self.view addSubview:_webView];
    
    // 让UIWebView执行脚本并监听回调
    _bridge = [WebViewJavascriptBridge bridgeForWebView:_webView handler:^(id data, WVJBResponseCallback responseCallback) {
        
        // 监听回调
        NSLog(@"%@", data);
    }];
}

@end

执行效果如下:

 

分析

WebViewJavascriptBridge.m 的源码里面有写着让webView执行js脚本的地方哦.

其实,我们只需要能够从UIWebView获取到值就行了,我们才不需要把值传递给UIwebView呢,有了这个UIWebView给iOS传值的功能,基本上能满足我们大部分的需求了哦.

最后,我将html页面进行修改,精简到大家能看懂为止:).

demo.html

<!doctype html>
<html><head>
    <style type='text/css'>
        html { font-family:Helvetica; color:#222; }
        h1 { color:steelblue; font-size:24px; margin-top:24px; }
        button { margin:0 3px 10px; font-size:12px; }
        .logLine { border-bottom:1px solid #ccc; padding:4px 2px; font-family:courier; font-size:11px; }
    </style>
</head><body>
    <h1>UIWebView与iOS直接交互</h1>
    
    
    <!--脚本开始的地方-->
    <script>
        
    <!--申明方法-->
    function connectWebViewJavascriptBridge(callback) {
        if (window.WebViewJavascriptBridge) {
            callback(WebViewJavascriptBridge)
        } else {
            document.addEventListener('WebViewJavascriptBridgeReady', function() {
                callback(WebViewJavascriptBridge)
            }, false)
        }
    }
    
    <!--激活方法-->
    connectWebViewJavascriptBridge(function(bridge) {

        <!--创建一个按钮-->
        var button = document.getElementById('buttons').appendChild(document.createElement('button'))
        button.innerHTML = '给iOS发送信息'
                                   
        <!--按钮点击事件的实现-->
        button.onclick = function(e) {
            e.preventDefault()
                                   
            <!--此处是你传参数的地方-->
            var data = 'YouXianMing - Just so easy :)'
                                   
            <!--使用bridge中的send发送数据-->
            bridge.send(data, function(responseData) {
            })
        }

        document.body.appendChild(document.createElement('br'))
    })
    
    <!--脚本结束的地方-->
    </script>
    <div id='buttons'></div> <div id='log'></div>
</body></html>

以下是修改后的执行效果:

 

附录:

WebViewJavascriptBridge与UIWebView交互原理

目录
相关文章
|
消息中间件 Java Spring
RocketMQ-JAVA客户端不同版本接入方式
RocketMQ4.0 RocketMQ5.0 JAVA接入 spring springboot
RocketMQ-JAVA客户端不同版本接入方式
vue3 wangEditor富文本自定义上传本地图片
Vue3和WangEditor都提供了上传本地图片的功能,可以结合使用实现自定义上传本地图片。
1816 0
|
Java Android开发
jvisualvm分析jvm内存溢出
jvisualvm分析jvm内存溢出
1672 0
jvisualvm分析jvm内存溢出
|
8月前
|
存储 JavaScript 前端开发
在NodeJS中使用npm包进行JS代码的混淆加密
总的来说,使用“javascript-obfuscator”包可以帮助我们在Node.js中轻松地混淆JavaScript代码。通过合理的配置,我们可以使混淆后的代码更难以理解,从而提高代码的保密性。
781 9
|
5月前
|
安全 Windows
电脑屏幕一闪一闪,电脑闪来闪去,问题解决办法
闪屏是电脑显示器常见问题,表现为画面闪烁或抖动,可能由显卡故障、驱动问题、软件冲突或硬件连接不良引起。解决方法包括检查显卡、更新驱动、调整刷新率及排查电源等问题。
1599 6
|
机器学习/深度学习 人工智能 自然语言处理
GLM-4V-Flash:智谱 AI 免费开放的图像理解大模型 API 接口
智谱AI推出的GLM-4V-Flash是一款专注于图像理解的免费开放大模型,提供API接口支持用户上传图片URL或Base64编码图片获取详细的图像描述。该模型通过深度学习和卷积神经网络技术,简化了图像分析流程,提高了开发效率,适用于内容审核、辅助视障人士、社交媒体、教育和电子商务等多个应用场景。
3909 14
GLM-4V-Flash:智谱 AI 免费开放的图像理解大模型 API 接口
|
11月前
|
编解码 人工智能 算法
DiffSynth:共建 Diffusion 开源生态
DiffSynth 是一个致力于共建 Diffusion 开源生态的项目,由段忠杰分享。该项目通过 Diffusion 技术回顾、模型生态互联与统一、视频生成技术等多方面探讨了如何构建强大的开源模型生态系统。DiffSynth-Studio 支持多种开源模型,优化计算性能,提供图像和视频生成等功能,并特别加强了对中文的支持。项目还引入了 ControlNet、loRA 等生态模型,实现风格转换和内容修改。未来将聚焦于视频时代的到来,推动视频生成技术的发展。
848 0
|
JSON 搜索推荐 C++
vscode如何更改背景颜色主题,黑色或白色?
【11月更文挑战第16天】在 VS Code 中更改背景颜色主题,可通过三种方式实现:1) 使用快捷键 Ctrl+K 和 Ctrl+T(Mac 上为 Command+K 和 Command+T)选择主题;2) 通过菜单中的“管理”-&gt;“颜色主题”选项选择;3) 修改 settings.json 文件中的 &quot;workbench.colorTheme&quot; 属性。此外,用户还可从扩展市场安装更多主题以满足个性化需求。
25138 6
|
编解码 Dart API
鸿蒙Flutter实战:06-使用ArkTs开发Flutter鸿蒙插件
本文介绍了如何开发一个 Flutter 鸿蒙插件,实现 Flutter 与鸿蒙的混合开发及双端消息通信。通过定义 `MethodChannel` 实现 Flutter 侧的 token 存取方法,并在鸿蒙侧编写 `EntryAbility` 和 `ForestPlugin`,使用鸿蒙的首选项 API 完成数据的读写操作。文章还提供了注意事项和参考资料,帮助开发者更好地理解和实现这一过程。
677 0
|
Java API 网络架构
利用Java Spring Boot构建微服务架构的实践探索
随着业务复杂性的增长和互联网技术的飞速发展,微服务架构已成为现代软件开发中不可或缺的一部分。本文旨在探讨如何利用Java Spring Boot框架构建微服务架构,包括微服务的定义、优势,以及通过实际案例展示如何设计、开发和部署微服务。我们将关注服务拆分、服务间通信、数据一致性、服务治理等核心问题,并探讨如何结合Spring Cloud生态中的组件来实现高效、可靠的微服务架构。