I am trying to create a class that takes a screenshot of the screen, makes it blurry and saves it to NSUserDefaults.- (UIImage*)blurImage{    UIImage* newImage = [[UIImage screenshot] applyBlurWithRadius:20                                                         blurType:BOXFILTER                                                        tintColor:[UIColor colorWithWhite:0.11f alpha:0.5]                                            saturationDeltaFactor:1.3                                                        maskImage:nil];    return newImage;}- (void)saveBlurredImageToUserDefaults{    [[NSUserDefaults standardUserDefaults] setObject:UIImagePNGRepresentation([self blurImage]) forKey:@blurredImage];    [[NSUserDefaults standardUserDefaults] synchronize];}applyBlurWithRadius:blurType:tintColor:saturationDeltaFactor:maskImage: is a UIImage category based on code provided by Apple at WWDC 2013. that can be found here in full.Here is that method in case that repo disappears:- (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius blurType: (BlurType) blurType tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage{    // Check pre-conditions.    if (self.size.width < 1 || self.size.height < 1) {        NSLog (@*** error: invalid size: (%.2f x %.2f). Both dimensions must be >= 1: %@, self.size.width, self.size.height, self);        return nil;    }    if (!self.CGImage) {        NSLog (@*** error: image must be backed by a CGImage: %@, self);        return nil;    }    if (maskImage && !maskImage.CGImage) {        NSLog (@*** error: maskImage must be backed by a CGImage: %@, maskImage);        return nil;    }    CGRect imageRect = { CGPointZero, self.size };    UIImage *effectImage = self;    BOOL hasBlur = blurRadius > __FLT_EPSILON__ && blurType != NOBLUR;    BOOL hasSaturationChange = fabs(saturationDeltaFactor - 1.) > __FLT_EPSILON__;    if (hasBlur || hasSaturationChange) {        UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);        CGContextRef effectInContext = UIGraphicsGetCurrentContext();        CGContextScaleCTM(effectInContext, 1.0, -1.0);        CGContextTranslateCTM(effectInContext, 0, -self.size.height);        CGContextDrawImage(effectInContext, imageRect, self.CGImage);        vImage_Buffer effectInBuffer;        effectInBuffer.data     = CGBitmapContextGetData(effectInContext);        effectInBuffer.width    = CGBitmapContextGetWidth(effectInContext);        effectInBuffer.height   = CGBitmapContextGetHeight(effectInContext);        effectInBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectInContext);        UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);        CGContextRef effectOutContext = UIGraphicsGetCurrentContext();        vImage_Buffer effectOutBuffer;        effectOutBuffer.data     = CGBitmapContextGetData(effectOutContext);        effectOutBuffer.width    = CGBitmapContextGetWidth(effectOutContext);        effectOutBuffer.height   = CGBitmapContextGetHeight(effectOutContext);        effectOutBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectOutContext);        if (hasBlur) {            // A description of how to compute the box kernel width from the Gaussian            // radius (aka standard deviation) appears in the SVG spec:            // http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement            //             // For larger values of 's' (s >= 2.0), an approximation can be used: Three            // successive box-blurs build a piece-wise quadratic convolution kernel, which            // approximates the Gaussian kernel to within roughly 3%.            //            // let d = floor(s * 3*sqrt(2*pi)/4 + 0.5)            //             // ... if d is odd, use three box-blurs of size 'd', centered on the output pixel.            //             CGFloat inputRadius = blurRadius * [[UIScreen mainScreen] scale];            uint32_t radius = floor(inputRadius * 3. * sqrt(2 * M_PI) / 4 + 0.5);            if (radius % 2 != 1) {                radius += 1; // force radius to be odd so that the three box-blur methodology works.            }            if (blurType == BOXFILTER)            {                vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);                vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);                vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);            }            else            {                vImageTentConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);            }        }        BOOL effectImageBuffersAreSwapped = NO;        if (hasSaturationChange) {            CGFloat s = saturationDeltaFactor;            CGFloat floatingPointSaturationMatrix[] = {                0.0722 + 0.9278 * s,  0.0722 - 0.0722 * s,  0.0722 - 0.0722 * s,  0,                0.7152 - 0.7152 * s,  0.7152 + 0.2848 * s,  0.7152 - 0.7152 * s,  0,                0.2126 - 0.2126 * s,  0.2126 - 0.2126 * s,  0.2126 + 0.7873 * s,  0,                                  0,                    0,                    0,  1,            };            const int32_t divisor = 256;            NSUInteger matrixSize = sizeof(floatingPointSaturationMatrix)/sizeof(floatingPointSaturationMatrix[0]);            int16_t saturationMatrix[matrixSize];            for (NSUInteger i = 0; i < matrixSize; ++i) {                saturationMatrix[i] = (int16_t)roundf(floatingPointSaturationMatrix[i] * divisor);            }            if (hasBlur) {                vImageMatrixMultiply_ARGB8888(&effectOutBuffer, &effectInBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags);                effectImageBuffersAreSwapped = YES;            }            else {                vImageMatrixMultiply_ARGB8888(&effectInBuffer, &effectOutBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags);            }        }        if (!effectImageBuffersAreSwapped)            effectImage = UIGraphicsGetImageFromCurrentImageContext();        UIGraphicsEndImageContext();        if (effectImageBuffersAreSwapped)            effectImage = UIGraphicsGetImageFromCurrentImageContext();        UIGraphicsEndImageContext();    }    // Set up output context.    UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);    CGContextRef outputContext = UIGraphicsGetCurrentContext();    CGContextScaleCTM(outputContext, 1.0, -1.0);    CGContextTranslateCTM(outputContext, 0, -self.size.height);    // Draw base image.    CGContextDrawImage(outputContext, imageRect, self.CGImage);    // Draw effect image.    if (hasBlur) {        CGContextSaveGState(outputContext);        if (maskImage) {            CGContextClipToMask(outputContext, imageRect, maskImage.CGImage);        }        CGContextDrawImage(outputContext, imageRect, effectImage.CGImage);        CGContextRestoreGState(outputContext);    }    // Add in color tint.    if (tintColor) {        CGContextSaveGState(outputContext);        CGContextSetFillColorWithColor(outputContext, tintColor.CGColor);        CGContextFillRect(outputContext, imageRect);        CGContextRestoreGState(outputContext);    }    // Output image is ready.    UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();    UIGraphicsEndImageContext();    return outputImage;}Now calling this takes only one line (+ alloc&init), which is pretty good to me, but is there anything else I should do?
Creating and saving blurred screenshots in iOS
design patterns;objective c;ios
Ultimately, it looks like your code has gone a long way toward being very convenient in the one spot you want to save a blurred screenshot to NSUserDefaults... but a long way toward being highly specific and not at all reusable.For starters, we don't need a class for this at all.  Classes should be thought of as things... as nouns... as the subject of a sentence.  Methods, meanwhile, should be thought of as actions... as verbs... as the predicate of a sentence.  We should create a class when we need to represent a thing.  We should create a method when we need to do an action.  We should not create a class simply because we feel like we need something to hold our collection of methods.Objective-C is a strict superset of C.  Anything you can do in C can also be done in Objective-C.  And in C, you don't even have classes!  So you certainly weren't creating classes just for the sake of holding a collection of methods!  But like in C, in Objective-C, we can create free functions.  Functions that do not belong to any classes.Also, importantly, in Objective-C, when we need to add actions to an existing thing, we can do that too!  If we keep with the grammar metaphor, the properties of a class are sort of like adjectives.  If we need to add adjectives to a class, we should create a subclass.  If all we need to do is add actions (verbs... methods...) to a class, then in Objective-C, we can create a category.Your code makes use of two good examples of using categories, so I'm not sure why your blurImage method is anything but a UIImage category and why you've created a class?So, let's make it a category:UIImage+Blur.h@interface UIImage (Blur)- (UIImage *)blurImage;@endUIImage+Blur.m@implementation UIImage (Blur)- (UIImage *)blurImage {    return [self applyBlurWithRadius:20                            blurType:BOXFILTER                           tintColor:[UIColor colorWithWhite:0.11f alpha:0.5]               saturationDeltaFactor:1.3                           maskImage:nil];}@endThough, a more specific name for this specific type of blur would probably be appropriate.  You may decide you want to create other convenience methods for other types of blurs.Now, we can get a blurred screenshot as simple as:UIImage *blurredScreenshot = [[UIImage screenshot] blurImage];And if we're really doing this so frequently, we can get rid of the nesting by adding another method to our category:+ (UIImage *)blurredScreenshot {    return [[UIImage screenshot] blurImage];}And then:UIImage *blurredScreenshot = [UIImage blurredScreenshot];The advantage here is that we've made it more convenient for us (created the blurredScreenshot method), but we haven't hampered the reusability, because we still have the screenshot and blurImage methods.  These methods do distinct things and anyone may want to use these individually at a later date (including yourself).As far as saving to NSUserDefaults?  This is already a one-liner.  Calling synchronize is almost always unnecessary and doing so can have a negative impact on your app's performance.  The only time you will lose data via not synchronized is if your app crashes or possibly if the user's device crashes.  If the former is a problem, calling synchronize isn't really the real fix, is it?  If the latter is the problem... I wouldn't bother with it... and tell the user to get their device fixed...And finally, one-lining things isn't always inherently good.  Code should be readable, not terse.  Fewer lines doesn't make code run faster, meanwhile, it does generally make human reading and debugging more difficult.Also, keys should typically be defined as a constant somewhere... I usually have a header file:NSUserDefaultsKeys.hNSString * const kUSERDEFKEY_BLURREDIMAGE = @blurredImage;So, with the given category above, I'd most likely implement it as such:UIImage *blurredScreenshot = [[UIImage screenshot] blurImage];NSData *blurredJPEGdata = UIImagePNGRepresentation(blurredScreenshot);[[NSUserDefaults standardDefaults] setObject:blurredJPEGdata                                       forKey:kUSERDEFKEY_BLURREDIMAGE];And I wouldn't necessarily try wrapping this up into any sort of convenience method or function.  This is just fine as is...