{"id":16977261,"url":"https://github.com/zhaoyiming0803/into-webviewjavascriptbridge","last_synced_at":"2026-04-20T13:36:52.710Z","repository":{"id":113416961,"uuid":"222202383","full_name":"zhaoyiming0803/into-WebViewJavascriptBridge","owner":"zhaoyiming0803","description":"Into WebViewJavascriptBridge, interaction between JavaScript and Native App","archived":false,"fork":false,"pushed_at":"2020-06-13T10:59:35.000Z","size":1080,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-21T22:12:31.221Z","etag":null,"topics":["objective-c","webviewjavascriptbridge"],"latest_commit_sha":null,"homepage":"","language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zhaoyiming0803.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-11-17T05:36:02.000Z","updated_at":"2023-07-01T20:04:33.000Z","dependencies_parsed_at":"2023-11-04T03:45:07.284Z","dependency_job_id":null,"html_url":"https://github.com/zhaoyiming0803/into-WebViewJavascriptBridge","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/zhaoyiming0803/into-WebViewJavascriptBridge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhaoyiming0803%2Finto-WebViewJavascriptBridge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhaoyiming0803%2Finto-WebViewJavascriptBridge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhaoyiming0803%2Finto-WebViewJavascriptBridge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhaoyiming0803%2Finto-WebViewJavascriptBridge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zhaoyiming0803","download_url":"https://codeload.github.com/zhaoyiming0803/into-WebViewJavascriptBridge/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhaoyiming0803%2Finto-WebViewJavascriptBridge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278577899,"owners_count":26009701,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-06T02:00:05.630Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["objective-c","webviewjavascriptbridge"],"created_at":"2024-10-14T01:28:26.885Z","updated_at":"2025-10-06T07:41:13.678Z","avatar_url":"https://github.com/zhaoyiming0803.png","language":"Objective-C","readme":"### into WebViewJavascriptBridge\n\n最近项目中，把 APP 和 小程序 里 80% 的页面都换成了 H5，目的是快速开发，方便热更新。\n\n前端除了要保证代码高度复用并且降低耦合，还要主动和负责 Native 开发的同学沟通，定义好协议，留下文档，方便后期维护。\n\n混合开发，最核心的是数据交互：\n\n- 小程序端：在不影响用户体验的情况下，直接或间接的使用现有规则进行开发。\n\n- Native端：使用了目前市面上成熟的 WebViewJavaScriptBridge 开源库。在 Android 端踩了一些坑，iOS 端没出现太大的问题。\n\n项目完成了，抽时间学习下 WebViewJavaScriptBridge 源码，顺便对这次 Hybrid 开发做下总结。\n\n### JavaScript 与 Native 交互的方式（以iOS为例）\n\n1、JS 调用 Native 方法：\n\n- Native 拦截 URL 跳转\n\n``` javascript\nwindow.location.href = 'Native自定义协议';\n```\n\n- 使用 WebKit，苹果官方推荐使用这种方式\n\n``` javascript\nwindow.webkit.messagehandlers.\u003cname\u003e.postMessage('xxx');\n```\n\n2、Native 调用 JS 方法\n\n前端将 JS function 暴露到全局 window 对象上， Native 在 web-view 中注入 JS 代码执行。\n\n以上方法如果单独使用，都比较麻烦，而且代码难以组织，Native 拦截 URL 跳转或使用 WebKit 更多时候是用在前端单向调用 Native 方法的场景，不支持 return 和 callback，只能做 send 操作，做不了 get 操作。\n\n3、使用 WebViewJavaScriptBridge 开源库\n\niOS 和 Android 对应的代码开源地址：\n\n[iOS WebViewJavascriptBridge](https://github.com/marcuswestin/WebViewJavascriptBridge)\n\n[Android JsBridge](https://github.com/lzyzsd/JsBridge)\n\n### WebViewJavaScriptBridge 实现机制\n\nWebViewJavaScriptBridge 很好的解决了 JS 和 Native 通信的问题，并且使我们能更好的组织代码，其原理也是根据以上两种方法做了进一步封装。\n\nJS 和 Native 需要互相调用，那么各自都需要做到两点：\n\n1、注册好方法，供对方调用\n\n2、调用对方已注册的方法\n\n![WebViewJavaScriptBridge交互图](https://github.com/zhaoyiming0803/into-WebViewJavascriptBridge/blob/master/docs/images/WebViewJavaScriptBridge%E4%BA%A4%E4%BA%92%E5%9B%BE.png)\n\niOS（WKWebView）对外暴露的API：\n\n``` objc\n- (void)registerHandler:(NSString*)handlerName handler:(WVJBHandler)handler;\n\n- (void)removeHandler:(NSString*)handlerName;\n\n- (void)callHandler:(NSString*)handlerName;\n- (void)callHandler:(NSString*)handlerName data:(id)data;\n- (void)callHandler:(NSString*)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback;\n\n- (void)reset;\n- (void)setWebViewDelegate:(id)webViewDelegate;\n- (void)disableJavscriptAlertBoxSafetyTimeout;\n```\n\nJavaScript 对外暴露的 API：\n\n``` javascript\nwindow.WebViewJavascriptBridge = {\n  registerHandler: registerHandler,\n  callHandler: callHandler,\n  disableJavscriptAlertBoxSafetyTimeout: disableJavscriptAlertBoxSafetyTimeout,\n  _fetchQueue: _fetchQueue,\n  _handleMessageFromObjC: _handleMessageFromObjC\n};\n```\n\n我们通常使用的也就是它们各自的 registerHandler 和 callHandler 方法。\n\n### WebViewJavaScriptBridge 目录结构\n\n1、WebViewJavascriptBridgeBase\n\n用来进行 bridge 初始化和消息处理的核心类，其保存了三个很重要的属性：\n\n- responseCallbacks：用于保存 Objective-C 与 javascript 环境相互调用的回调模块。通过 _uniqueId 加上时间戳来确定每个调用的回调。\n\n- messageHandlers：用于保存 Objective-C 环境注册的方法，key 是方法名，value 是这个方法对应的回调 block\n\n- startupMessageQueue：保存类实例化过程中需要发送给 JavaScirpt 环境的消息。\n\n2、WebViewJavascriptBridge\n\nbridge 入口类，判断当前 WebView 的类型是 UIWebView 或 WKWebView，执行相应的逻辑。\n\n3、WKWebViewJavascriptBridge\n\n针对 WKWebView 做的一层封装，主要用来执行 JS 代码，以及实现 WKWebView 的代理方法，并通过拦截 URL 来通知 WebViewJavascriptBridgeBase 做相应操作。本次源码学习，也是以 WKWebViewJavascriptBridge 为主，忽略 UIWebView。\n\n4、WebViewJavascriptBridge_JS\n\n其代码会被注入到 WebView 中，用于 JavaScript 端的 register 和 call 操作。\n\n### 本次源码（iOS WebViewJavascriptBridge）学习笔记全部记录在 docs 目录下。\n\n[iOS 初始化 WebViewJavascriptBridge](https://github.com/zhaoyiming0803/into-WebViewJavascriptBridge/blob/master/docs/iOS%E5%88%9D%E5%A7%8B%E5%8C%96WebViewJavascriptBridge.md)\n\n[JavaScript 初始化 Bridge](https://github.com/zhaoyiming0803/into-WebViewJavascriptBridge/blob/master/docs/JavaScript%E5%88%9D%E5%A7%8B%E5%8C%96Bridge.md)\n\n[JavaScript 主动调用 iOS 方法](https://github.com/zhaoyiming0803/into-WebViewJavascriptBridge/blob/master/docs/JavaScript%E4%B8%BB%E5%8A%A8%E8%B0%83%E7%94%A8iOS%20%E6%96%B9%E6%B3%95.md)\n\n[iOS 主动调用 JavaScript 方法](https://github.com/zhaoyiming0803/into-WebViewJavascriptBridge/blob/master/docs/iOS%E4%B8%BB%E5%8A%A8%E8%B0%83%E7%94%A8JavaScript%E6%96%B9%E6%B3%95.md)\n\n### 代码示例全部放在 demo 目录下，包括 JavaScript 和 Objective-C 初始化及具体调用方法。\n\n[bridge.js](https://github.com/zhaoyiming0803/into-WebViewJavascriptBridge/blob/master/demo/bridge.js)\n\n[YMBridgeController.m](https://github.com/zhaoyiming0803/into-WebViewJavascriptBridge/blob/master/demo/YMBridgeController.m)","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzhaoyiming0803%2Finto-webviewjavascriptbridge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzhaoyiming0803%2Finto-webviewjavascriptbridge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzhaoyiming0803%2Finto-webviewjavascriptbridge/lists"}