Refactor

Refactoring Examples

At first glance it appears that the two sections of code are different but in reality they are the same with transliterated names.
The problem is repeated code, the DRY (Do not Repeat Yourself) principle is being ignored.

Original:

#define kVGFileCacheFolder_1_2 @“aaa”

#define kVGFileDb_1_3 @“bbb”

    

    

+ (void)removeOldCacheFolder {

    

    BOOL oldCacheFolderRemoved = [[NSUserDefaults standardUserDefaults] boolForKey:kVGFileCacheFolder_1_2];

    

    if(!oldCacheFolderRemoved){

        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

        NSString *documentsDirectory = [paths objectAtIndex:0]; //Get documents folder  

        NSString *cacheDirectory = [documentsDirectory stringByAppendingPathComponent:kVGFileCacheFolder_1_2]; 

        

        if ([[NSFileManager defaultManager] fileExistsAtPath:cacheDirectory]) {

            NSError *error = nil;

            

            if (!([[NSFileManager defaultManager] removeItemAtPath:cacheDirectory error:&error])) {

                NSLog(@”Unresolved error %@, %@”, error, [error userInfo]);

            }

            else{

                [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kVGFileCacheFolder_1_2];

            }

        }

    }

    

    BOOL oldSQLFileDeleted = [[NSUserDefaults standardUserDefaults] boolForKey:kVGFileDb_1_3];

    

    if(!oldSQLFileDeleted){

        

        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

        NSString *documentsDirectory = [paths objectAtIndex:0]; //Get documents folder

        

        NSString *sqlFile = [documentsDirectory stringByAppendingPathComponent:kVGFileDb_1_3]; 

        

        if ([[NSFileManager defaultManager] fileExistsAtPath:sqlFile]) {

            NSError *error = nil;

            

            if (!([[NSFileManager defaultManager] removeItemAtPath:sqlFile error:&error])) {

                NSLog(@”Unresolved error %@, %@”, error, [error userInfo]);

            }

            else{

                [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kVGFileDb_1_3];

            }

        }

    }

}

Refactored:

static NSString* const kVGFileCacheFolder_1_2 = @”aaa”;

static NSString* const kVGFileDb_1_3          = @”bbb”;

+ (void)removeOldCacheFolders {

    [self removeCacheFolder:kVGFileCacheFolder_1_2];

    [self removeCacheFolder:kVGFileDb_1_3];

}

+ (void)removeCacheFolder:(NSString *)fileName {

    BOOL oldFileHasBeenDeleted = [[NSUserDefaults standardUserDefaults] boolForKey:fileName] == YES;

    if(oldFileHasBeenDeleted == YES)

        return;

    NSString *filePath = [self filePathForDocumentFileName:fileName];

    BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath];

    if (fileExists == NO)

        return;

    NSError *error = nil;

    if ([[NSFileManager defaultManager] removeItemAtPath:filePath error:&error])

        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:fileName];

    else

        NSLog(@”Unresolved error %@, %@”, error, [error userInfo]);

}

+ (NSString *)filePathForDocumentFileName:(NSString *)fileName {

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *documentsDirectory = [paths objectAtIndex:0];

    return [documentsDirectory stringByAppendingPathComponent:fileName];

}

Refactored (eXtreme):

static NSString* const kVGFileCacheFolder_1_2 = @”aaa”;

static NSString* const kVGFileDb_1_3          = @”bbb”;

+ (void)removeOldCacheFolders {

    [self removeCacheFolder:kVGFileCacheFolder_1_2];

    [self removeCacheFolder:kVGFileDb_1_3];

}

+ (void)removeCacheFolder:(NSString *)fileName {

    if([self cacheFileHasBeenDeleted:fileName])

        return;

    

    NSString *filePath = [self filePathForDocumentFileName:fileName];

    if ([self cacheFileExists:filePath])

        [self removeFile:filePath];

}

- (BOOL)cacheFileHasBeenDeleted:(NSString *)fileName {

    return [[NSUserDefaults standardUserDefaults] boolForKey:fileName] == YES;

}

- (BOOL)cacheFileExists:(NSString *)filePath {

    return [[NSFileManager defaultManager] fileExistsAtPath:filePath];

}

- (void)removeFile:(NSString *)filePath {

    NSError *error = nil;

    if ([[NSFileManager defaultManager] removeItemAtPath:filePath error:&error])

        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:filePath];

    else

        NSLog(@”Unresolved error %@, %@”, error, [error userInfo]);

}

+ (NSString *)filePathForDocumentFileName:(NSString *)fileName {

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *documentsDirectory = [paths objectAtIndex:0];

    return [documentsDirectory stringByAppendingPathComponent:fileName];

}

One Response to Refactor

  1. Aniciitha says:

    Thanks for writing this up Ce9dric!
    One thing to make it easier: make a user defined setting and then the editing the project as text and replacing it part can be done entirely within the Xcode UI:So “- Add a User-Defined Setting…” remains as you have it, but the next two steps might be:- Select the user defined setting name in the left column, then select “Add Build Setting Condition” from the gear pop-up button at the lower left of the setting window. – Select “Any iPhone Simulator”, and “Any Architecture” (the default)

Leave a Reply