@bud-fe/h5-native-bridge
v1.0.4
Published
H5与原生App通信工具库
Downloads
59
Readme
H5-Native-Bridge
H5与原生App通信工具库,使用TypeScript开发,Vite构建。
功能特性
- 提供H5页面与原生App的双向通信能力
- 支持位置信息获取、设备信息、媒体保存、页面导航等原生能力调用
- 类型安全,完全使用TypeScript开发
- 支持开发环境下模拟数据
- 支持多种打包格式(ESM, UMD)
- 单元测试覆盖核心功能
安装
npm install h5-native-bridge打包
npm run build使用方法
基本使用
import nativeBridge from 'h5-native-bridge';
// 获取位置信息
nativeBridge
.getLocation({
enableHighAccuracy: true,
})
.then((location) => {
console.log('✅ 位置信息:', location);
})
.catch((error) => {
console.error('获取位置失败:', error);
});开启调试模式
import nativeBridge from 'h5-native-bridge';
// 开启调试模式可以在控制台查看详细日志
nativeBridge.setDebug(true);完整示例
import nativeBridge from 'h5-native-bridge';
// 获取位置信息
nativeBridge
.getLocation({
enableHighAccuracy: true,
})
.then((location) => {
console.log('✅ 位置信息:', location);
})
.catch((error) => {
console.error('获取位置失败:', error);
});
// 获取WiFi列表
nativeBridge
.getWifiList()
.then((deviceInfo) => {
console.log('设备信息:', deviceInfo);
})
.catch((error) => {
console.error('获取WiFi失败:', error);
});
// 保存图片
nativeBridge
.saveImage({
url: 'https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/ecbfab94b77e4c73a9635f4639bf41fd~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5Y-q5oOz6Lq65bmz5LiN5oOz5Yqq5Yqb:q75.awebp?rk3s=f64ab15b&x-expires=1747911373&x-signature=bqy63dhMBpzZuILHRSVE37RuRLM%3D',
})
.then((deviceInfo) => {
console.log('图片信息:', deviceInfo);
})
.catch((error) => {
console.error('图片保存失败:', error);
});原生App对接说明
Android端
// MainActivity.java
public class MainActivity extends AppCompatActivity {
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webview);
// 初始化WebView
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
// 注册JavaScript接口
webView.addJavascriptInterface(new NativeBridgeInterface(), "AndroidBridge");
// 加载H5页面
webView.loadUrl("https://your-app-url.com");
}
// JavaScript接口
private class NativeBridgeInterface {
@JavascriptInterface
public void postMessage(String message) {
try {
JSONObject jsonMessage = new JSONObject(message);
String action = jsonMessage.getString("action");
JSONObject params = jsonMessage.getJSONObject("params");
String callbackId = jsonMessage.getString("callbackId");
// 根据action处理不同的请求
if ("getLocation".equals(action)) {
handleGetLocation(callbackId, params);
}
// 其他action处理...
} catch (JSONException e) {
e.printStackTrace();
}
}
private void handleGetLocation(final String callbackId, JSONObject params) {
// 获取定位权限并执行定位
// 获取到位置后,调用JavaScript回调
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
// 假设已获取到位置信息
JSONObject location = new JSONObject();
location.put("latitude", 31.2304);
location.put("longitude", 121.4737);
location.put("accuracy", 10);
location.put("timestamp", System.currentTimeMillis());
location.put("address", "上海市某某路123号");
// 调用JavaScript回调
String script = "window.nativeBridgeCallback('" + callbackId + "', 'success', " + location.toString() + ")";
webView.evaluateJavascript(script, null);
} catch (Exception e) {
// 处理错误
String script = "window.nativeBridgeCallback('" + callbackId + "', 'fail', {message: '" + e.getMessage() + "'})";
webView.evaluateJavascript(script, null);
}
}
});
}
}
}iOS端
// ViewController.swift
import UIKit
import WebKit
class ViewController: UIViewController, WKScriptMessageHandler, WKNavigationDelegate {
var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
// 配置WKWebView
let configuration = WKWebViewConfiguration()
let userContentController = WKUserContentController()
// 注册JS消息处理,名称为 "nativeBridge"
userContentController.add(self, name: "nativeBridge")
configuration.userContentController = userContentController
// 创建WKWebView
webView = WKWebView(frame: view.bounds, configuration: configuration)
webView.navigationDelegate = self
view.addSubview(webView)
// 加载H5页面
if let url = URL(string: "https://your-app-url.com") {
webView.load(URLRequest(url: url))
}
}
// 处理来自JS的消息
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "nativeBridge", let messageBody = message.body as? String {
do {
// 解析JS发送的JSON消息
if let messageData = messageBody.data(using: .utf8),
let jsonMessage = try JSONSerialization.jsonObject(with: messageData) as? [String: Any],
let action = jsonMessage["action"] as? String,
let params = jsonMessage["params"] as? [String: Any],
let callbackId = jsonMessage["callbackId"] as? String {
// 根据action处理不同的请求
switch action {
case "getLocation":
handleGetLocation(callbackId: callbackId, params: params)
case "navigate":
handleNavigate(callbackId: callbackId, params: params)
case "saveImage":
handleSaveImage(callbackId: callbackId, params: params)
case "getDeviceInfo":
handleGetDeviceInfo(callbackId: callbackId, params: params)
case "getWifiList":
handleGetWifiList(callbackId: callbackId, params: params)
default:
let error = ["message": "未知的action: \(action)"]
let script = "window.nativeBridgeCallback('\(callbackId)', 'fail', \(toJSONString(error)))"
webView.evaluateJavaScript(script, completionHandler: nil)
}
} else {
throw NSError(domain: "", code: -1, userInfo: [NSLocalizedDescriptionKey: "无效的JSON消息"])
}
} catch {
// 处理解析错误
let error = ["message": "消息解析失败: \(error.localizedDescription)"]
if let callbackId = (message.body as? [String: Any])?["callbackId"] as? String {
let script = "window.nativeBridgeCallback('\(callbackId)', 'fail', \(toJSONString(error)))"
webView.evaluateJavaScript(script, completionHandler: nil)
}
}
}
}
// 处理获取位置请求
private func handleGetLocation(callbackId: String, params: [String: Any]) {
// 获取定位权限并执行定位
// 假设已获取到位置信息
let location: [String: Any] = [
"latitude": 31.2304,
"longitude": 121.4737,
"accuracy": 10,
"timestamp": Date().timeIntervalSince1970 * 1000,
"address": "上海市某某路123号"
]
// 调用JavaScript回调
let script = "window.nativeBridgeCallback('\(callbackId)', 'success', \(toJSONString(location)))"
webView.evaluateJavaScript(script) { _, error in
if let error = error {
print("JavaScript执行错误: \(error)")
}
}
}
// 处理导航请求
private func handleNavigate(callbackId: String, params: [String: Any]) {
// 实现导航逻辑,例如跳转到指定页面
let response: [String: Any] = ["status": "success"]
let script = "window.nativeBridgeCallback('\(callbackId)', 'success', \(toJSONString(response)))"
webView.evaluateJavaScript(script, completionHandler: nil)
}
// 处理保存图片请求
private func handleSaveImage(callbackId: String, params: [String: Any]) {
// 实现图片保存逻辑
let response: [String: Any] = ["status": "success"]
let script = "window.nativeBridgeCallback('\(callbackId)', 'success', \(toJSONString(response)))"
webView.evaluateJavaScript(script, completionHandler: nil)
}
// 处理获取设备信息请求
private func handleGetDeviceInfo(callbackId: String, params: [String: Any]) {
// 实现设备信息获取逻辑
let deviceInfo: [String: Any] = [
"platform": "ios",
"osVersion": UIDevice.current.systemVersion,
"deviceModel": UIDevice.current.model,
"appVersion": Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "",
"uuid": UIDevice.current.identifierForVendor?.uuidString ?? "",
"screenWidth": UIScreen.main.bounds.width,
"screenHeight": UIScreen.main.bounds.height,
"pixelRatio": UIScreen.main.scale,
"networkType": "wifi",
"language": Locale.current.languageCode ?? "en"
]
let script = "window.nativeBridgeCallback('\(callbackId)', 'success', \(toJSONString(deviceInfo)))"
webView.evaluateJavaScript(script, completionHandler: nil)
}
// 处理获取WiFi列表请求
private func handleGetWifiList(callbackId: String, params: [String: Any]) {
// 实现WiFi列表获取逻辑
let wifiList: [[String: Any]] = [
["ssid": "WiFi-1", "signalStrength": -50],
["ssid": "WiFi-2", "signalStrength": -70]
]
let response: [String: Any] = [
"resultCode": 0,
"resultMessage": "成功",
"wifiList": wifiList
]
let script = "window.nativeBridgeCallback('\(callbackId)', 'success', \(toJSONString(response)))"
webView.evaluateJavaScript(script, completionHandler: nil)
}
// 辅助函数:将字典转为JSON字符串
private func toJSONString(_ dict: [String: Any]) -> String {
if let data = try? JSONSerialization.data(withJSONObject: dict),
let str = String(data: data, encoding: .utf8) {
return str
}
return "{}"
}
}
## 本地开发
```bash
# 安装依赖
npm install
# 启动开发服务器
npm run dev
# 构建生产版本
npm run build
# 运行测试
npm run test许可证
MIT
贡献指南
欢迎提交issue和PR。
