插件 0.4.0

Plug 0.4.0

Tomasz Lewandowski 维护。



Plug 0.4.0

  • Tomasz Lewandowski

Build Status codecov Carthage compatible Cocoapods Platform Platform License

Plug 是一个跨平台插件架构微型框架和插件管理器,使用纯 Swift 编写。它允许定义在指定插件点激活插件时必须满足的规则。

需求

开发

项目使用以下工具进行开发

  1. XCodeGen
  2. Cocoapods
  3. SwiftLint

安装

要开始使用 Plug,您首先需要决定如何将其集成到您的项目中。Plug 支持以下工具

Cocoapods

要使用 Cocoapods 安装 Plug,请按照以下步骤操作

  1. 在您的 Podfile 中添加以下条目
pod 'Plug'
  1. 然后运行 pod install

Carthage

使用Carthage安装Plug的步骤如下:

  1. 请在你的Cartfile中添加以下条目
github "lewandowskit93/Plug"
  1. 然后运行carthage update

Swift Package Manager

使用Swift Package Manager安装Plug的步骤如下:

  1. 在您的Package.swift文件中添加以下依赖项包.package(url: "https://github.com/lewandowskit93/Plug.git", from: "0.4.0")
  2. 在您的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中使用的功能和概念的简要概述。

Plug example

插件

插件是指实现了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 协议来定义自己的规则。可用的一些规则有:AtomRuleEnabledRuleDisabledRuleInvertedRuleAllOfRuleAnyOfRuleNoneOfRuleAnyRule

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