扩展你的编辑器:AztecEditor-iOS 插件系统架构深入解析与自定义插件开发教程
【免费下载链接】AztecEditor-iOSA reusable native iOS visual HTML text editor component.项目地址: https://gitcode.com/gh_mirrors/az/AztecEditor-iOS
AztecEditor-iOS 是一款开箱即用的原生 iOS 可视化 HTML 文本编辑器组件,它的强大之处不仅在于所见即所得的富文本编辑能力,更在于一套设计精妙的插件系统。通过这套架构,你可以在不改动编辑器核心源码的前提下,自由扩展输入、输出与渲染逻辑——这正是 AztecEditor-iOS 被 WordPress 等大型项目选用的关键原因。本文将从零开始,带你深入解析插件系统的架构设计,并手把手完成一个自定义插件开发实例。
什么是 AztecEditor-iOS 插件系统?
简单来说,插件系统是 AztecEditor-iOS 提供的一套"钩子"机制:当编辑器把 HTML 转成富文本(输入过程)或把富文本转回 HTML(输出过程)时,插件可以在这些关键节点介入,改写 HTML 字符串或解析后的节点树,从而实现自定义标签、短代码(Shortcode)乃至 Gutenberg 块级元素的支持。
对于新手而言,可以把它理解成"编辑器的中间件"——不需要继承 TextView,不需要修改框架源码,只要实现几个协议方法,就能让编辑器听懂你自定义的 HTML。
插件系统核心架构:三大支柱
整个插件体系由三个核心文件构成,理解了它们,你就掌握了插件开发的全部诀窍。
Plugin 基类:插件的入口
Plugin.swift 是所有插件的基类。它只做两件事:携带一个输入定制器和输出定制器,并在插件被加载时回调loaded(textView:)方法,让你有机会在编辑器上做初始化工作(比如替换剪贴板代理)。
open class Plugin { public let inputCustomizer: PluginInputCustomizer? public let outputCustomizer: PluginOutputCustomizer? open func loaded(textView: TextView) {} }PluginInputCustomizer:接管"HTML → 富文本"
PluginInputCustomizer.swift 定义了三个可选方法,分别在不同阶段处理输入:
process(html:):在 HTML 字符串被解析成节点树之前,做字符串级预处理;process(htmlTree:):在节点树解析完成后,对树结构做增删改;converter(for:):为特定 HTML 元素提供专属的转换器,决定它如何变成富文本格式。
由于所有方法都有默认空实现,你只需覆写需要的部分,非常轻量。
PluginOutputCustomizer:接管"富文本 → HTML"
PluginOutputCustomizer.swift 则是反向管线的定制器,支持:
process(html:)与process(htmlTree:):分别对输出 HTML 字符串和节点树做后处理;convert(_:paragraphProperty:):把富文本的段落属性还原成对应的 HTML 元素;convert(_:attachment:):把图片、视频等附件还原成自定义节点;converter(for:):为元素提供专属的序列化转换器。
插件是如何被加载与执行的?
插件的加载入口在 TextView.swift,一行代码即可完成:
textView.load(MyPlugin())调用后,插件会被交给 PluginManager.swift 统一管理。这个管理器是插件的"调度中枢":它按加载顺序把输入定制器、输出定制器串联成一条处理管线(Pipeline),并保证每个插件都能依次处理数据。更巧妙的是,PluginManager 还通过扩展实现了AttributedStringSerializerCustomizer、AttributedStringParserCustomizer、HTMLSerializerCustomizer三个协议,将插件能力无缝接入编辑器的转换流程。
输入输出管线:两个方向的数据旅程
AztecEditor-iOS 的插件系统本质上是"双管线"设计:
- 输入管线:HTML 字符串 →
process(html:)→ 解析成节点树 →process(htmlTree:)→ 元素转换器 → 富文本; - 输出管线:富文本 → 段落属性/附件转换 → 节点树 →
process(htmlTree:)→ 序列化成 HTML →process(html:)。
字符串级的处理通常依赖 HTMLProcessor.swift 这样的正则处理器,或 PipelineProcessor.swift 把多个处理器串行执行。这种"先字符串、后节点树"的两阶段设计,让插件既能快速处理文本,也能精确操作结构。
真实案例:WordPressPlugin 是怎么工作的
理论再多,不如看一个生产级案例。WordPressPlugin.swift 是 AztecEditor-iOS 自带的旗舰插件,它同时注册了输入与输出定制器,并利用loaded(textView:)替换了编辑器的剪贴板代理。
它的输入定制器 WordPressInputCustomizer.swift 展示了插件系统的全部三种用法:
- 字符串级处理:用
PipelineProcessor组合了 Caption 短代码、Gallery 短代码、视频短代码和 AutoP 等多个处理器; - 树级处理:通过 GutenbergInputHTMLTreeProcessor.swift 把 Gutenberg 注释块解析成块级节点;
- 元素转换器:为
gallery、gutenblock等元素注册专属转换器。
比如 CaptionShortcodeInputProcessor.swift 的职责,就是把[caption]短代码重写为标准化的<figure><img><figcaption>结构——这种"短代码翻译"正是插件系统的拿手好戏。
自定义插件开发教程:三步写出你的第一个插件
下面我们动手实现一个简单插件,把自定义标签[note]内容[/note]转换为带样式的富文本。只需三步。
第一步:创建输入定制器,把短代码转成标准 HTML
利用process(html:),在字符串阶段就把[note]替换成<div class="note">,这样编辑器就能用普通段落样式渲染它。
第二步:实现 Plugin 子类并组合
创建一个NotePlugin类,继承Plugin,在初始化时注入自定义的输入定制器。
第三步:加载插件
let textView = TextView(defaultFont: font, defaultMissingImage: UIImage()) textView.load(NotePlugin())完成!现在粘贴包含[note]标签的 HTML 时,编辑器会自动以提示框样式呈现——全程没有改动任何框架代码。
进阶:如何开发复杂插件
如果你需要开发更复杂的插件(比如支持自定义媒体附件),可以参考以下完整流程:
- 定义元素类型:在 ElementNode.swift 中注册新的块级元素;
- 实现双向转换器:输入侧实现
ElementConverter(HTML → 富文本),输出侧实现ElementToTagConverter(富文本 → HTML),两套转换器分别挂在输入/输出定制器上; - 处理附件:如果插件需要支持图片、视频等附件,实现 AttachmentToElementConverter.swift 并在输出定制器的
convert(_:attachment:)中注册; - 加载与验证:通过
textView.load(_:)加载插件,并用单元测试覆盖往返转换的一致性。
这套流程在 WordPress 的 Gallery、Gutenpack 等插件中均有完整实现,是绝佳的参考范本。
总结
AztecEditor-iOS 的插件系统用最少的抽象,解决了富文本编辑器最常见的扩展难题:如何在不侵入核心的前提下,让编辑器理解千变万化的 HTML。通过Plugin+ 输入/输出定制器 + 节点树处理器这套组合拳,无论是短代码、自定义标签还是 Gutenberg 块,都能优雅落地。对于想要打造自有 iOS 富文本编辑器的团队来说,掌握这套插件架构,就等于拥有了无限扩展的可能性——现在就打开 Example 工程,动手试试吧!
【免费下载链接】AztecEditor-iOSA reusable native iOS visual HTML text editor component.项目地址: https://gitcode.com/gh_mirrors/az/AztecEditor-iOS
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考