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.