@bud-fe/h5-native-bridge 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,352 @@
1
+ # H5-Native-Bridge
2
+
3
+ H5与原生App通信工具库,使用TypeScript开发,Vite构建。
4
+
5
+ ## 功能特性
6
+
7
+ - 提供H5页面与原生App的双向通信能力
8
+ - 支持位置信息获取、设备信息、媒体保存、页面导航等原生能力调用
9
+ - 类型安全,完全使用TypeScript开发
10
+ - 支持开发环境下模拟数据
11
+ - 支持多种打包格式(ESM, UMD)
12
+ - 单元测试覆盖核心功能
13
+
14
+ ## 安装
15
+
16
+ ```bash
17
+ npm install h5-native-bridge
18
+ ```
19
+
20
+ ## 打包
21
+
22
+ ```bash
23
+ npm run build
24
+ ```
25
+
26
+ ## 使用方法
27
+
28
+ ### 基本使用
29
+
30
+ ```javascript
31
+ import nativeBridge from 'h5-native-bridge';
32
+
33
+ // 获取位置信息
34
+ nativeBridge
35
+ .getLocation({
36
+ enableHighAccuracy: true,
37
+ })
38
+ .then((location) => {
39
+ console.log('✅ 位置信息:', location);
40
+ })
41
+ .catch((error) => {
42
+ console.error('获取位置失败:', error);
43
+ });
44
+ ```
45
+
46
+ ### 开启调试模式
47
+
48
+ ```javascript
49
+ import nativeBridge from 'h5-native-bridge';
50
+
51
+ // 开启调试模式可以在控制台查看详细日志
52
+ nativeBridge.setDebug(true);
53
+ ```
54
+
55
+ ### 完整示例
56
+
57
+ ```javascript
58
+ import nativeBridge from 'h5-native-bridge';
59
+
60
+ // 获取位置信息
61
+ nativeBridge
62
+ .getLocation({
63
+ enableHighAccuracy: true,
64
+ })
65
+ .then((location) => {
66
+ console.log('✅ 位置信息:', location);
67
+ })
68
+ .catch((error) => {
69
+ console.error('获取位置失败:', error);
70
+ });
71
+
72
+ // 获取WiFi列表
73
+ nativeBridge
74
+ .getWifiList()
75
+ .then((deviceInfo) => {
76
+ console.log('设备信息:', deviceInfo);
77
+ })
78
+ .catch((error) => {
79
+ console.error('获取WiFi失败:', error);
80
+ });
81
+
82
+ // 保存图片
83
+ nativeBridge
84
+ .saveImage({
85
+ 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',
86
+ })
87
+ .then((deviceInfo) => {
88
+ console.log('图片信息:', deviceInfo);
89
+ })
90
+ .catch((error) => {
91
+ console.error('图片保存失败:', error);
92
+ });
93
+ ```
94
+
95
+ ## 原生App对接说明
96
+
97
+ ### Android端
98
+
99
+ ```java
100
+ // MainActivity.java
101
+ public class MainActivity extends AppCompatActivity {
102
+ private WebView webView;
103
+
104
+ @Override
105
+ protected void onCreate(Bundle savedInstanceState) {
106
+ super.onCreate(savedInstanceState);
107
+ setContentView(R.layout.activity_main);
108
+
109
+ webView = findViewById(R.id.webview);
110
+
111
+ // 初始化WebView
112
+ WebSettings settings = webView.getSettings();
113
+ settings.setJavaScriptEnabled(true);
114
+
115
+ // 注册JavaScript接口
116
+ webView.addJavascriptInterface(new NativeBridgeInterface(), "AndroidBridge");
117
+
118
+ // 加载H5页面
119
+ webView.loadUrl("https://your-app-url.com");
120
+ }
121
+
122
+ // JavaScript接口
123
+ private class NativeBridgeInterface {
124
+ @JavascriptInterface
125
+ public void postMessage(String message) {
126
+ try {
127
+ JSONObject jsonMessage = new JSONObject(message);
128
+ String action = jsonMessage.getString("action");
129
+ JSONObject params = jsonMessage.getJSONObject("params");
130
+ String callbackId = jsonMessage.getString("callbackId");
131
+
132
+ // 根据action处理不同的请求
133
+ if ("getLocation".equals(action)) {
134
+ handleGetLocation(callbackId, params);
135
+ }
136
+ // 其他action处理...
137
+
138
+ } catch (JSONException e) {
139
+ e.printStackTrace();
140
+ }
141
+ }
142
+
143
+ private void handleGetLocation(final String callbackId, JSONObject params) {
144
+ // 获取定位权限并执行定位
145
+ // 获取到位置后,调用JavaScript回调
146
+ runOnUiThread(new Runnable() {
147
+ @Override
148
+ public void run() {
149
+ try {
150
+ // 假设已获取到位置信息
151
+ JSONObject location = new JSONObject();
152
+ location.put("latitude", 31.2304);
153
+ location.put("longitude", 121.4737);
154
+ location.put("accuracy", 10);
155
+ location.put("timestamp", System.currentTimeMillis());
156
+ location.put("address", "上海市某某路123号");
157
+
158
+ // 调用JavaScript回调
159
+ String script = "window.nativeBridgeCallback('" + callbackId + "', 'success', " + location.toString() + ")";
160
+ webView.evaluateJavascript(script, null);
161
+ } catch (Exception e) {
162
+ // 处理错误
163
+ String script = "window.nativeBridgeCallback('" + callbackId + "', 'fail', {message: '" + e.getMessage() + "'})";
164
+ webView.evaluateJavascript(script, null);
165
+ }
166
+ }
167
+ });
168
+ }
169
+ }
170
+ }
171
+ ```
172
+
173
+ ### iOS端
174
+
175
+ ````swift
176
+ // ViewController.swift
177
+ import UIKit
178
+ import WebKit
179
+
180
+ class ViewController: UIViewController, WKScriptMessageHandler, WKNavigationDelegate {
181
+
182
+ var webView: WKWebView!
183
+
184
+ override func viewDidLoad() {
185
+ super.viewDidLoad()
186
+
187
+ // 配置WKWebView
188
+ let configuration = WKWebViewConfiguration()
189
+ let userContentController = WKUserContentController()
190
+
191
+ // 注册JS消息处理,名称为 "nativeBridge"
192
+ userContentController.add(self, name: "nativeBridge")
193
+ configuration.userContentController = userContentController
194
+
195
+ // 创建WKWebView
196
+ webView = WKWebView(frame: view.bounds, configuration: configuration)
197
+ webView.navigationDelegate = self
198
+ view.addSubview(webView)
199
+
200
+ // 加载H5页面
201
+ if let url = URL(string: "https://your-app-url.com") {
202
+ webView.load(URLRequest(url: url))
203
+ }
204
+ }
205
+
206
+ // 处理来自JS的消息
207
+ func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
208
+ if message.name == "nativeBridge", let messageBody = message.body as? String {
209
+ do {
210
+ // 解析JS发送的JSON消息
211
+ if let messageData = messageBody.data(using: .utf8),
212
+ let jsonMessage = try JSONSerialization.jsonObject(with: messageData) as? [String: Any],
213
+ let action = jsonMessage["action"] as? String,
214
+ let params = jsonMessage["params"] as? [String: Any],
215
+ let callbackId = jsonMessage["callbackId"] as? String {
216
+
217
+ // 根据action处理不同的请求
218
+ switch action {
219
+ case "getLocation":
220
+ handleGetLocation(callbackId: callbackId, params: params)
221
+ case "navigate":
222
+ handleNavigate(callbackId: callbackId, params: params)
223
+ case "saveImage":
224
+ handleSaveImage(callbackId: callbackId, params: params)
225
+ case "getDeviceInfo":
226
+ handleGetDeviceInfo(callbackId: callbackId, params: params)
227
+ case "getWifiList":
228
+ handleGetWifiList(callbackId: callbackId, params: params)
229
+ default:
230
+ let error = ["message": "未知的action: \(action)"]
231
+ let script = "window.nativeBridgeCallback('\(callbackId)', 'fail', \(toJSONString(error)))"
232
+ webView.evaluateJavaScript(script, completionHandler: nil)
233
+ }
234
+ } else {
235
+ throw NSError(domain: "", code: -1, userInfo: [NSLocalizedDescriptionKey: "无效的JSON消息"])
236
+ }
237
+ } catch {
238
+ // 处理解析错误
239
+ let error = ["message": "消息解析失败: \(error.localizedDescription)"]
240
+ if let callbackId = (message.body as? [String: Any])?["callbackId"] as? String {
241
+ let script = "window.nativeBridgeCallback('\(callbackId)', 'fail', \(toJSONString(error)))"
242
+ webView.evaluateJavaScript(script, completionHandler: nil)
243
+ }
244
+ }
245
+ }
246
+ }
247
+
248
+ // 处理获取位置请求
249
+ private func handleGetLocation(callbackId: String, params: [String: Any]) {
250
+ // 获取定位权限并执行定位
251
+ // 假设已获取到位置信息
252
+ let location: [String: Any] = [
253
+ "latitude": 31.2304,
254
+ "longitude": 121.4737,
255
+ "accuracy": 10,
256
+ "timestamp": Date().timeIntervalSince1970 * 1000,
257
+ "address": "上海市某某路123号"
258
+ ]
259
+
260
+ // 调用JavaScript回调
261
+ let script = "window.nativeBridgeCallback('\(callbackId)', 'success', \(toJSONString(location)))"
262
+ webView.evaluateJavaScript(script) { _, error in
263
+ if let error = error {
264
+ print("JavaScript执行错误: \(error)")
265
+ }
266
+ }
267
+ }
268
+
269
+ // 处理导航请求
270
+ private func handleNavigate(callbackId: String, params: [String: Any]) {
271
+ // 实现导航逻辑,例如跳转到指定页面
272
+ let response: [String: Any] = ["status": "success"]
273
+ let script = "window.nativeBridgeCallback('\(callbackId)', 'success', \(toJSONString(response)))"
274
+ webView.evaluateJavaScript(script, completionHandler: nil)
275
+ }
276
+
277
+ // 处理保存图片请求
278
+ private func handleSaveImage(callbackId: String, params: [String: Any]) {
279
+ // 实现图片保存逻辑
280
+ let response: [String: Any] = ["status": "success"]
281
+ let script = "window.nativeBridgeCallback('\(callbackId)', 'success', \(toJSONString(response)))"
282
+ webView.evaluateJavaScript(script, completionHandler: nil)
283
+ }
284
+
285
+ // 处理获取设备信息请求
286
+ private func handleGetDeviceInfo(callbackId: String, params: [String: Any]) {
287
+ // 实现设备信息获取逻辑
288
+ let deviceInfo: [String: Any] = [
289
+ "platform": "ios",
290
+ "osVersion": UIDevice.current.systemVersion,
291
+ "deviceModel": UIDevice.current.model,
292
+ "appVersion": Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "",
293
+ "uuid": UIDevice.current.identifierForVendor?.uuidString ?? "",
294
+ "screenWidth": UIScreen.main.bounds.width,
295
+ "screenHeight": UIScreen.main.bounds.height,
296
+ "pixelRatio": UIScreen.main.scale,
297
+ "networkType": "wifi",
298
+ "language": Locale.current.languageCode ?? "en"
299
+ ]
300
+ let script = "window.nativeBridgeCallback('\(callbackId)', 'success', \(toJSONString(deviceInfo)))"
301
+ webView.evaluateJavaScript(script, completionHandler: nil)
302
+ }
303
+
304
+ // 处理获取WiFi列表请求
305
+ private func handleGetWifiList(callbackId: String, params: [String: Any]) {
306
+ // 实现WiFi列表获取逻辑
307
+ let wifiList: [[String: Any]] = [
308
+ ["ssid": "WiFi-1", "signalStrength": -50],
309
+ ["ssid": "WiFi-2", "signalStrength": -70]
310
+ ]
311
+ let response: [String: Any] = [
312
+ "resultCode": 0,
313
+ "resultMessage": "成功",
314
+ "wifiList": wifiList
315
+ ]
316
+ let script = "window.nativeBridgeCallback('\(callbackId)', 'success', \(toJSONString(response)))"
317
+ webView.evaluateJavaScript(script, completionHandler: nil)
318
+ }
319
+
320
+ // 辅助函数:将字典转为JSON字符串
321
+ private func toJSONString(_ dict: [String: Any]) -> String {
322
+ if let data = try? JSONSerialization.data(withJSONObject: dict),
323
+ let str = String(data: data, encoding: .utf8) {
324
+ return str
325
+ }
326
+ return "{}"
327
+ }
328
+ }
329
+
330
+ ## 本地开发
331
+
332
+ ```bash
333
+ # 安装依赖
334
+ npm install
335
+
336
+ # 启动开发服务器
337
+ npm run dev
338
+
339
+ # 构建生产版本
340
+ npm run build
341
+
342
+ # 运行测试
343
+ npm run test
344
+ ````
345
+
346
+ ## 许可证
347
+
348
+ MIT
349
+
350
+ ## 贡献指南
351
+
352
+ 欢迎提交issue和PR。
File without changes
@@ -0,0 +1,3 @@
1
+ export * from './src/index'
2
+ import NativeBridge from './src/index'
3
+ export default NativeBridge