基于 WKWebView 的官方 iOS WebView 插件webview_flutter_wkwebview 深度指南【免费下载链接】pluginsPlugins for Flutter maintained by the Flutter team项目地址: https://gitcode.com/gh_mirrors/pl/pluginswebview_flutter_wkwebview是 Flutter 官方插件webview_flutter在 Apple 平台iOS / macOS上的 WKWebView 实现属于官方联邦插件federated plugin中的平台实现包。本文以该包根目录的 README.md 为骨架结合仓库源码与 iOS 原生类系统讲解它在应用中的接入方式、endorsed 机制背后的注册原理、面向原生代码的 External Native API 用法以及基于 pigeon/mockito 的二次开发与贡献流程帮助你既能开箱即用也能在需要时深入到原生WKWebView层做定制。一、包定位Apple 平台上的 WKWebView 实现根据 pubspec.yaml 的描述这是一个基于 Apple 的 WKWebView 控件提供 WebView Widget 的 Flutter 插件。它并不是一个独立可用的包而是webview_flutter在 iOS/macOS 上的官方平台实现版本3.1.0SDK 约束sdk: 2.17.0 3.0.0、flutter: 3.0.0插件声明implements: webview_flutterios.pluginClass为FLTWebViewFlutterPlugindartPluginClass为WebKitWebViewPlatform依赖webview_flutter_platform_interface ^2.0.0平台接口抽象层与path ^1.8.0。说明当前仓库中的webview_flutter生态采用主包app-facing API 平台接口包抽象层 各平台实现包的联邦插件架构。本包即为抽象层WebViewPlatform在 Apple 平台上的具体实现。二、接入方式endorsed 插件与零配置使用README 明确指出该包是 endorsed官方背书插件因此应用开发者无需直接依赖它只需要正常使用webview_flutter主包即可dependencies: webview_flutter: ^4.0.0 # 以实际发布的版本为准当应用依赖了webview_flutter后本包会被自动引入无需在pubspec.yaml中显式声明也无需任何额外初始化代码——这正是 endorsed 联邦插件机制带来的体验平台实现包通过implements: webview_flutter声明自己归属的接口包由 Flutter 工具链在构建时自动按平台挑选正确的实现。2.1 背后的注册机制WebKitWebViewPlatform从源码层面看零配置的实质是平台实现包在初始化时向平台接口注册自己。核心入口位于 lib/src/webkit_webview_platform.dart/// Implementation of [WebViewPlatform] using the WebKit API. class WebKitWebViewPlatform extends WebViewPlatform { /// Registers this class as the default instance of [WebViewPlatform]. static void registerWith() { WebViewPlatform.instance WebKitWebViewPlatform(); } override WebKitWebViewController createPlatformWebViewController( PlatformWebViewControllerCreationParams params, ) WebKitWebViewController(params); override WebKitNavigationDelegate createPlatformNavigationDelegate( PlatformNavigationDelegateCreationParams params, ) WebKitNavigationDelegate(params); override WebKitWebViewWidget createPlatformWebViewWidget( PlatformWebViewWidgetCreationParams params, ) WebKitWebViewWidget(params); override WebKitWebViewCookieManager createPlatformCookieManager( PlatformWebViewCookieManagerCreationParams params, ) WebKitWebViewCookieManager(params); }registerWith()将WebKitWebViewPlatform设为WebViewPlatform.instance全局默认实现之后主包创建的任何 WebView 组件控制器、导航委托、Widget、Cookie 管理器都会经由这里的工厂方法落到 WebKit 原生实现上。该类的对外导出集中在 lib/webview_flutter_wkwebview.dart它同时导出了WebKitWebViewController、WebKitWebViewCookieManager与WebKitWebViewPlatform三个公开符号。三、External Native API在 iOS 原生代码中访问 WKWebViewREADME 中的核心技术亮点是插件提供的面向原生代码的外部 APIExternal Native API。常规情况下Flutter 开发者只通过 Dart API 与 WebView 交互但当你的 App 或插件需要在 iOS 原生层对 WKWebView 做深度定制例如叠加原生手势、接入原生广告 SDK、与原生 JS 桥接时可以通过这套 API 拿到真实的WKWebView实例。3.1 访问约定与破坏性变更承诺该 API 遵循一个重要的兼容性约定README 原文要点外部 API 与 Dart API 共享破坏性变更breaking change约定任何不向后兼容的类变更只会伴随插件major 版本升级而发生除外部 API 之外的其余原生代码不遵循破坏性变更约定因此 App 或插件客户端不应使用任何其他原生 API。换句话说仓库ios/Classes/下绝大多数类各*HostApi、FWFInstanceManager等都属于内部实现随时可能变化只有FWFWebViewFlutterWKWebViewExternalAPI是受版本约定保护的公开契约。3.2 导入方式与核心类在 Objective-C 代码中通过模块导入即可import webview_flutter_wkwebview;导入后即可访问原生类FWFWebViewFlutterWKWebViewExternalAPI。该类声明于 ios/Classes/FWFWebViewFlutterWKWebViewExternalAPI.h核心方法如下interface FWFWebViewFlutterWKWebViewExternalAPI : NSObject /** * Retrieves the WKWebView that is associated with identifier. * * param identifier The associated identifier of the WebView. * param registry The plugin registry the FLTWebViewFlutterPlugin should belong to. * return The WKWebView associated with identifier or nil if not found. */ (nullable WKWebView *)webViewForIdentifier:(long)identifier withPluginRegistry:(idFlutterPluginRegistry)registry; end参数含义参数类型说明identifierlong与底层 WKWebView 关联的标识符可在 Dart 侧通过WebKitWebViewController.webViewIdentifier获取registryidFlutterPluginRegistry插件注册表若其中未挂载FLTWebViewFlutterPlugin实例方法返回nil返回值WKWebView *可空与identifier关联的 WKWebView找不到时返回nil3.3 Dart 侧如何拿到 identifier在 Flutter/Dart 侧先创建WebKitWebViewController然后通过其webViewIdentifiergetter 拿到标识符。该 getter 定义于 lib/src/webkit_webview_controller.dart/// Identifier used to retrieve the underlying native WKWebView. /// /// This is typically used by other plugins to retrieve the native WKWebView /// from an FWFInstanceManager. int get webViewIdentifier _webKitParams._instanceManager.getIdentifier(_webView)!;结合原生实现ios/Classes/FWFWebViewFlutterWKWebViewExternalAPI.m完整的调用链为Dart 侧WebKitWebViewController通过InstanceManager为底层WKWebView分配一个递增的整型 identifierwebViewIdentifier将该 identifier 暴露给上层调用者原生侧FWFWebViewFlutterWKWebViewExternalAPI.webViewForIdentifier:withPluginRegistry:从插件注册表取出FWFInstanceManager用同一 identifier 反查原生对象FWFInstanceManager *instanceManager (FWFInstanceManager *)[registry valuePublishedByPlugin:FLTWebViewFlutterPlugin]; id instance [instanceManager instanceForIdentifier:identifier]; if ([instance isKindOfClass:[WKWebView class]]) { return instance; } return nil;校验实例类型为WKWebView后返回给原生调用方。3.4 典型应用场景示例假设你需要在 iOS 原生层给 WebView 注入一段自定义 WKUserScript大致流程如下// 1. 从 Dart 侧通过 MethodChannel/EventChannel 把 identifier 传递到原生层 long identifier ...; // 来自 WebKitWebViewController.webViewIdentifier // 2. 通过 External Native API 获取底层 WKWebView WKWebView *webView [FWFWebViewFlutterWKWebViewExternalAPI webViewForIdentifier:identifier withPluginRegistry:self.registrar]; if (webView nil) { // 插件尚未注册或 identifier 无效 return; } // 3. 直接操作原生 WKWebView示例注入用户脚本 WKUserScript *script [[WKUserScript alloc] initWithSource:... injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO]; [webView.configuration.userContentController addUserScript:script];需要说明的是该特性自3.1.0版本引入见 CHANGELOG.md 首条 Adds support to access nativeWKWebView使用时请确认你的依赖解析到了该版本及以上。四、源码结构从 Dart 到原生 Host API理解本包源码布局有助于评估哪些内容属于受保护的外部 API哪些属于随时可能变化的内部实现。仓库目录结构如下packages/webview_flutter/webview_flutter_wkwebview/ ├── lib/ # Dart 侧实现 │ ├── webview_flutter_wkwebview.dart # 公开导出 │ └── src/ │ ├── common/ # InstanceManager、pigeon 生成的 g.dart │ ├── foundation/ # Foundation 框架 API 实现 │ ├── ui_kit/ # UIKit 框架 API 实现 │ ├── web_kit/ # WebKit API 实现 │ └── webkit_*.dart # 平台实现controller/cookie_manager/widget ├── ios/Classes/ # 原生实现全部 .h/.m ├── pigeons/web_kit.dart # pigeon 通信接口定义通信层唯一真源 ├── example/ # 示例工程含 RunnerTests 原生单测 └── test/ # Dart 单测含 mockito 生成的 .mocks.dartios/Classes/下的原生类大致分三类公开外部 APIFWFWebViewFlutterWKWebViewExternalAPI唯一受版本约定保护pigeon 生成的 Host APIFWFWebViewHostApi、FWFNavigationDelegateHostApi、FWFWebViewConfigurationHostApi、FWFHTTPCookieStoreHostApi、FWFWebsiteDataStoreHostApi、FWFUserContentControllerHostApi、FWFScriptMessageHandlerHostApi、FWFPreferencesHostApi、FWFScrollViewHostApi、FWFUIViewHostApi、FWFUIDelegateHostApi等均由pigeons/web_kit.dart生成见 FWFGeneratedWebKitApis.h基础设施FWFInstanceManager原生对象与 identifier 的双向映射见 FWFInstanceManager.h、FWFDataConverters、插件入口FLTWebViewFlutterPlugin。五、二次开发与贡献pigeon 与 mockito 代码生成流程README 的 Contributing 部分说明了本包的两条关键开发工作流对想要修改通信层或为包贡献代码的开发者非常实用。5.1 修改通信接口后重新生成 pigeon 代码本包使用 pigeonDart 侧的 lib/src/common/web_kit.g.dart 与原生侧的FWFGeneratedWebKitApis.h/.m都是由它生成的产物。编辑完通信接口后执行以下命令重新生成通信层flutter pub run pigeon --input pigeons/web_kit.dart注当前仓库的开发依赖锁定 pigeon^4.2.13见 pubspec.yaml 的dev_dependencies命令在包根目录下运行。修改接口后一般还需要同步更新test/src/common/test_web_kit.g.dart对应的测试桩可参照 test/src/common/instance_manager_test.dart 等既有测试的写法。5.2 重新生成 mockito 测试替身除 pigeon 外本包还使用 mockito 为测试生成 mock 对象。修改了需要被 mock 的类如WebKitProxy、各 delegate后运行flutter pub run build_runner build --delete-conflicting-outputs生成结果即test/目录下的*.mocks.dart文件例如 test/webkit_webview_controller_test.mocks.dart 与 test/webkit_navigation_delegate_test.mocks.dart。测试用例分布可参考test/webkit_webview_controller_test.dart控制器行为test/webkit_webview_cookie_manager_test.dartCookie 管理test/webkit_webview_widget_test.dartWidget 组装test/src/foundation/foundation_test.dart、test/src/ui_kit/ui_kit_test.dart、test/src/web_kit/web_kit_test.dart分层 API 实现。原生侧还有对应的 Objective-C 单元测试位于 example/ios/RunnerTests/如FWFNavigationDelegateHostApiTests.m、FWFWebViewConfigurationHostApiTests.m可直接验证各 Host API 与FWFInstanceManager的 identifier 传递行为。5.3 原生侧工程信息若需要集成或排查原生问题可参考 podspec ios/webview_flutter_wkwebview.podspec 的关键配置source_files/public_header_filesClasses/**/*.{h,m}全部原生源码与公开头文件module_mapClasses/FlutterWebView.modulemap支撑import webview_flutter_wkwebview;的模块化导入platformiOS 9.0 起pod_target_xcconfig开启DEFINES_MODULE并排除模拟器 i386 架构。六、小结webview_flutter_wkwebview是一个典型的 endorsed 联邦插件应用侧零配置即可在 iOS/macOS 上获得基于 WKWebView 的完整 WebView 能力而通过受版本约定保护的FWFWebViewFlutterWKWebViewExternalAPI原生开发者还能安全地拿到底层WKWebView实例做深度定制。同时其基于 pigeon 的通信层设计与 mockito 驱动的测试体系也为维护者和贡献者提供了清晰的二次开发路径。若需了解 Dart 侧主包 API 的完整用法可继续阅读 webview_flutter 包文档若需自定义其他平台的实现可参考同仓库下的webview_flutter_android与webview_flutter_web等兄弟包。【免费下载链接】pluginsPlugins for Flutter maintained by the Flutter team项目地址: https://gitcode.com/gh_mirrors/pl/plugins创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
在赛灵思FPGA上部署YOLOv2目标检测:从Darknet权重到硬件加速全流程解析 简介:FPGA凭借可编程与高能效特性成为深度学习边缘部署的理想选择。面向AI嵌入式开发者与FPGA工程师,这份资源聚焦在赛灵思平台上完成YOLOv2实时目标检测算法的移植,覆盖模型优化、硬件逻辑设计、Vivado HLS生成IP核、系统集成与验证等关键环… · 2026/9/21 1:36:39
山特UPS电源原理图深度解析:从读图顺序到故障维修实战 简介:山特UPS电源原理图是一份面向电源维修人员、电子工程师及电气专业学习者的电路图纸资料,旨在帮助读者理解不间断电源的完整工作链路与排障要点。图纸覆盖输入电路、直流电源部分、输出电路与控制电路,清晰标出交流转直流、直流稳压、直流… · 2026/9/21 1:35:39
罩极电机检验标准全解析:从绕组电阻到耐压测试的出厂检验指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/21 1:35:39
WTF终端仪表盘10个必装模块精选:从GitHub到天气,打造你的终极信息中枢 WTF终端仪表盘10个必装模块精选:从GitHub到天气,打造你的终极信息中枢 【免费下载链接】wtf The personal information dashboard for your terminal 项目地址: https://gitcode.com/gh_mirrors/wt/wtf
WTF(wtfutil)是一款免费开源的终端个人仪表盘,专为开发者和技术爱好… · 2026/9/21 2:28:48
CodeIgniter XML Helper 完全指南:xml_convert 用法、原理与实战 后端Web框架 【免费下载链接】CodeIgniter Open Source PHP Framework (originally from EllisLab) 项目地址: https://gitcode.com/gh_mirrors/co/CodeIgniter 点击查看 免费下载 XML Helper 是 CodeIgniter 框架中用于辅助处理 XML 数据的函数集合,其… · 2026/9/21 2:28:48
用户画像7大维度实战:从数据清洗到标签落地 用户画像这几年已经被说烂了,但真正能把画像做扎实、能直接支撑业务决策的大数据分析师,其实并不多。尤其是旅游网站这类垂直领域,用户的决策链路长、场景碎片化,画像要是只停留在“性别年龄城市”的粗粒度标签,那基本… · 2026/9/21 2:28:48
飞书与腾讯会议API对接实战:SSO、鉴权与事件回调全解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/21 2:28:48
Zephyr 板级支持详解:Renesas EK-RX261 评估套件的硬件特性、烧录与调试指南 Zephyr 板级支持详解:Renesas EK-RX261 评估套件的硬件特性、烧录与调试指南 【免费下载链接】zephyr Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures. 项目… · 2026/9/21 2:28:48
16页月度薪酬分析报告:从数据到决策的完整方法论 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/21 2:27:48
Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化 直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡… · 2026/9/21 0:02:39
Word表格编号全攻略:从列表编号到题注交叉引用 写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技… · 2026/9/21 0:02:39
从第一个站到第二个站:独立开发者的静态网站选型与落地实践 1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&… · 2026/9/20 0:00:41
agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and … · 2026/9/21 0:00:18
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,… · 2026/9/21 0:00:18