ContentTransformable
@MainActor
public protocol ContentTransformable<Input, Output> : Sendable
A protocol that defines an object capable of transforming a value of one type into a value of another type.
Conforming types receive a value of the associated Input type, apply a transformation to it, and return a value of the associated Output type. The transformation may throw if the input is invalid or the transformation cannot be completed.
This protocol serves two roles in an ActionSequence:
- Transforming a sequence step’s output for the next step, via
step(_:inputTransformer:)or anActionBranchConfiguration‘stransformerparameter. In this roleInputandOutputare typically the same type: the transformation changes the value, not the type (e.g. an array of images into an array of file models, both cases of the same content enum). - Converting an Interactor’s raw request result into a sequence step’s
ContentType, viaActionConfiguration’sresultTransformerparameter. This is only needed when an Interactor’sRequest.ResultDatatype differs from the step’sContentType. For example, an API Interactor might define its ownResultDataenum whose cases represent each supported endpoint, and a transformer packages that into theContentTypeused elsewhere in the sequence.
Example: transforming a sequence step’s output
In this example transformer we’re taking an array of images as input and transforming them into an array of models containing the image data and filenames to save them to. Since this transforms a step’s output for use by the next step, Input and Output are both inferred as AppContentType.
struct ImageFileTransformer: ContentTransformable {
func transform(input: AppContentType) throws -> AppContentType {
guard case .images(let images) = input else { return input }
let timestamp = Int(Date().timeIntervalSince1970)
let models: [DataModel] = try images.enumerated().map { index, image in
guard let data = image.pngData() else {
throw SequenceDemoError.invalidImage
}
return DataModel(data: data, fileName: "fetched-image-\(timestamp)-\(index).png")
}
}
}
Example: converting an Interactor’s result
Here we’re taking a FilterResultType value returned by an image-filtering Interactor and converting it into the AppContentType used throughout the rest of the sequence. ResultData (FilterResultType) and ContentType (AppContentType) are inferred as different types.
struct ApplyImageFilterResultTransformer: ContentTransformable {
func transform(input: FilterResultType) throws -> AppContentType {
switch input {
case .filteredImages(let urls):
return .savedFiles(urls: urls)
}
}
}
-
The type this transformer receives.
Declaration
Swift
associatedtype Input : ContentTypeable -
The content type this transformer produces.
Declaration
Swift
associatedtype Output : ContentTypeable -
Transforms the given input value and returns the converted result.
Throws
An error if the transformation cannot be applied to the given input.Parameters
inputThe value to transform.
Return Value
The converted value in the form of a
ContentType.
View on GitHub