When dealing with complex object creation in an iOS application you may feel the need for a cleaner and more fluent approach.
During my latest development my colleague @alexiskinsella set up a pattern based on providers in order to mimic the factory behaviour we often find in languages such as Java.
Recently, in the occasion of a side project, I am studying a slightly different approach, based on this article by Matthias Wessendorf.
What I am willing to do is an image builder which creates UIImages on which a GPUImageFilter is applied.
The result I came to is as follows:
+ (SMFilteredImageBuilder *)builderWithConfigurationBlock:(FilteredImageConfigurationBlock)configBlock
{
return [[self alloc] initWithConfigurationBlock:configBlock];
}
- (id)initWithConfigurationBlock:(FilteredImageConfigurationBlock)configBlock
{
if (self = [super init]) {
self.configuration = [SMFilteredImageConfiguration configuration];
if (configBlock) {
configBlock(self.configuration);
}
}
return self;
}
- (UIImage *)build
{
[self.configuration.imagePicture processImage];
return [self.configuration.filter imageFromCurrentlyProcessedOutput];
}
@interface SMFilteredImageConfiguration : NSObject @property GPUImageFilter *filter; @property GPUImagePicture *imagePicture; + (instancetype)configuration; @end
- (void)saveFilteredImage:(UIImage *)image
{
SMFilteredImageBuilder *imageBuilder = [SMFilteredImageBuilder builderWithConfigurationBlock:^(SMFilteredImageConfiguration *configuration){
GPUImagePicture *sourceImagePicture = [[GPUImagePicture alloc] initWithImage:image];
configuration.filter = [GPUImageFilter filterForSquaredImageFromImagePicture:sourceImagePicture withSide:100.0];
configuration.imagePicture = sourceImagePicture;
}];
UIImage *filteredImage = [imageBuilder build];
[filteredImage saveToDocumentsFolderWithName:@"Filtered.png"];
}
This should make for a quite readable code with a reduced number of lines of code in the method that invokes the builder.