Plug 是一个跨平台插件架构微型框架和插件管理器,使用纯 Swift 编写。它允许定义在指定插件点激活插件时必须满足的规则。
需求
开发
项目使用以下工具进行开发
安装
要开始使用 Plug,您首先需要决定如何将其集成到您的项目中。Plug 支持以下工具
Cocoapods
要使用 Cocoapods 安装 Plug,请按照以下步骤操作
- 在您的 Podfile 中添加以下条目
pod 'Plug'
- 然后运行
pod install
。
Carthage
使用Carthage安装Plug的步骤如下:
- 请在你的Cartfile中添加以下条目
github "lewandowskit93/Plug"
- 然后运行
carthage update
Swift Package Manager
使用Swift Package Manager安装Plug的步骤如下:
- 在您的
Package.swift
文件中添加以下依赖项包.package(url: "https://github.com/lewandowskit93/Plug.git", from: "0.4.0")
- 在您的
Package.swift
文件中添加以下目标依赖项dependencies: ["Plug"])
例如,可能如下所示
import PackageDescription
let package = Package(
name: "YourLibrary",
products: [
.library(
name: "YourLibrary",
targets: ["YourLibrary"])
],
dependencies: [
.package(url: "https://github.com/lewandowskit93/Plug.git", from: "0.4.0")
],
targets: [
.target(
name: "YourLibrary",
dependencies: ["Plug"])
]
)
概述
以下是对Plug中使用的功能和概念的简要概述。
插件
插件是指实现了PPlugin
协议的任何内容。您可以定义您的插件是什么,以及它们可以做什么。
例如,这里展示了ViewPlugin,它可以返回单个SwiftUI视图
public final class ViewPlugin<V: View>: PPlugin {
private let builder: () -> V
public init(builder: @escaping () -> V) {
self.builder = builder
}
public var view: some View {
return builder()
}
}
规则解析上下文
规则解析上下文是指实现了PRuleResolvingContext
的任何内容。在Plug中,所有内容都是基于PRuleResolvingContext泛型的。它可以提供额外的信息以决定哪些插件已被启用。
规则
规则 根据上下文确定是否返回插件。您可以通过实现 PRule 协议来定义自己的规则。可用的一些规则有:AtomRule、EnabledRule、DisabledRule、InvertedRule、AllOfRule、AnyOfRule、NoneOfRule、AnyRule。
PluginPoint
PluginPoint 定义了一个单一的插槽,插件可以附加到该插槽。单个插件点可以具有多个插件及其规则描述。具有分层结构,这意味着插件点可以有 子插件点。应用于插件点的规则也应用于其子插件点。可以使用 PluginPointBuilder 构建插件点。
DSL
Plug 定义了一些操作符和 DSL 以缩短插件点的构建过程。可用的操作符是
- 使用操作符添加插件:Builder <+ Plugin
- 使用操作符移除插件:Builder <- Plugin
- 使用操作符添加规则:Builder §+ Rule
- 使用操作符移除规则:Builder §- Rule
- 使用操作符添加子插件点:Builder |+ PluginPoint
- 使用操作符移除子插件点:Builder |- PluginPoint
- 使用操作符完成构建:Builder^
还有用于规则构建的操作符
- 反转规则:!AnyRule
- 所有规则都满足:&&[AnyRule]
- 没有规则满足:~~[AnyRule]
- 任意规则满足:||[AnyRule]
示例
这是插件点的一个示例定义,该插件点允许两个插件功能存在于 FooContext 已启用的情况下。
var pluginPoint = PluginPointBuilder()
.add(child: PluginPointBuilder()
.add(plugin: pluginFactory.feature1Plugin())
.add(rule: FeatureEnabledRule(id: "feature_1").any())
.build()
)
.add(child: PluginPointBuilder()
.add(plugin: pluginFactory.feature2Plugin())
.add(rule: FeatureEnabledRule(id: "feature_2").any())
.build()
).build()
var availablePlugins = pluginPoint.getAvailablePlugins(context: FooContext())
可以使用操作符如下定义相同的插件点
var pluginPoint = (
PluginPointBuilder()
|+ (
PluginPointBuilder()
<+ pluginFactory.feature1Plugin()
§+ FeatureEnabledRule(id: "feature_1").any()
)^
|+ (
PluginPointBuilder()
<+ pluginFactory.feature2Plugin()
§+ FeatureEnabledRule(id: "feature_2").any()
)^
)^
var availablePlugins = pluginPoint.getAvailablePlugins(context: FooContext())
或者可以使用 DSL 如下定义
var pluginPoint = PluginPoint {
child {
PluginPoint {
plugin(contextType: Context.self) { pluginFactory.feature1Plugin() }
rule(pluginType: Plugin.self) { FeatureEnabledRule(id: "feature_1").any() }
}
}
child {
PluginPoint {
plugin(contextType: Context.self) { pluginFactory.feature2Plugin() }
rule(pluginType: Plugin.self) { FeatureEnabledRule(id: "feature_2").any() }
}
}
}
有关更详细的示例,请参阅源代码。
贡献
项目由 Tomasz Lewandowski 创建和维护。
如果你添加了新的功能或修复了错误,你可以创建一个拉取请求。如果你有任何功能请求,请随时提交。
许可协议
插件遵循MIT许可协议。更多信息请参阅License.md。