PluginTask

🧩 支持插件的任务

PluginTask 是一个自定义的 Task,允许用户添加插件来修改其行为。可以向 PluginTask 实例添加 插件,以在任务的主要操作之前或之后执行额外的功能。这使得在不修改其原始实现的情况下轻松修改任务的行为成为可能。

用法

创建 TaskPluginManager

TaskPluginManager 负责管理已注册的插件。您可以通过使用 Plugin 实例数组初始化它来创建一个新的 TaskPluginManager 实例。

class ImageTaskPluginManager: TaskPluginManager<Void> {
    var image: Image?
}

创建 TaskPlugin

在创建 PluginTask 之前,您需要创建一个 TaskPlugin 来实现您想要添加的额外功能。 TaskPlugin 是一个符合 Plugin 协议并实现所需的 handle 方法的 Swift 结构体或类。

struct ImageDownloadingPlugin: TaskPlugin {
    var keyPath: WritableKeyPath<ImageTaskPluginManager, Image?> = \.image

    func handle(value: URL, output: inout Image?) async throws {
        let data: Data = try await fetchImage(url: value)
        let image: UIImage = UIImage(data: data)!
        output = Image(uiImage: image)
    }
}

在这个例子中,我们定义了一个自定义的 TaskPluginManager,它包含一个属性来保存下载的图片。然后,我们定义一个 TaskPlugin,它从给定的 URL 下载图片并将其存储在 TaskPluginManager 中。

创建 PluginTask

要创建 PluginTask,您需要使用 TaskPluginManager 初始化它。 TaskPluginManager 负责管理插件并在任务执行期间的适当时间调用它们。

let taskPluginManager = ImageTaskPluginManager()
let pluginTask: Task<Void, Error> = PluginTask(manager: taskPluginManager) { manager in
    let url = URL(string: "https://example.com/image.jpg")!
    try await manager.handle(value: url)
}

在这个例子中,我们创建了一个新的 ImageTaskPluginManager 实例,并使用它来初始化一个新的 PluginTask。 然后,我们定义任务的主要操作,即从 URL 下载图片并使用 handle 方法将其存储在 TaskPluginManager 中。