Refactoring Examples
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];
}
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)