The implementation scheme of extracting the proxy method in iOS

In development, we often encounter setting a proxy and implementing a proxy method in the proxy. Sometimes we encounter a situation where both classes are proxy objects of a certain class, and the proxy methods implemented are the same. At this time, we can consider extracting the proxy methods in the two classes, encapsulating them into a class, setting the class as an attribute of the two classes, and passing the required value to the proxy object.

ExamplePlease add picture description

Please add picture description
‘As shown in the above two pictures, both the personal center page and the setting page have some setting-related options, and the click operation is the same. Here we can use the click proxy method
Extract it into a proxy object to achieve the purpose of code reuse

Partial code

Personal page

- (NSMutableArray *)createDataList {
    NSMutableArray *arr = [[NSMutableArray alloc] init];

    if([TPUserDefault instance].userBO){
        MeConfigModel *secondModel2 = [[MeConfigModel alloc] init];
        secondModel2.cellType = MeCellType_account;
        secondModel2.cellStyle = MeCellStyle_itemCell;
        secondModel2.title = @"Account and Security";
        secondModel2. cellHeight = 48 * rectScale();
        secondModel2.isHiddenLine = NO;
        [arr addObject:secondModel2];
    }

    MeConfigModel *secondModel3 = [[MeConfigModel alloc] init];
    secondModel3.cellType = MeCellType_clearMemnory;
    secondModel3.cellStyle = MeCellStyle_itemCell;
    secondModel3.title = @"Clean cache";
    secondModel3.isHiddenLine = NO;
    NSString *cachePath = CachePath(@"");
    NSString *string = [NSString stringWithFormat:@"%.2fM",[self folderSizeAtPath:cachePath]];
    secondModel3.subTitle = string;
    secondModel3. cellHeight = 48 * rectScale();
    
    MeConfigModel *secondModel4 = [[MeConfigModel alloc] init];
    secondModel4.cellType = MeCellType_push;
    secondModel4.cellStyle = MeCellStyle_itemCell;
    secondModel4.title = @"Push Settings";
    secondModel4.isHiddenLine = NO;
    secondModel4. cellHeight = 48 * rectScale();
    
    MeConfigModel *secondModel5 = [[MeConfigModel alloc] init];
    secondModel5.cellType = MeCellType_sugess;
    secondModel5. cellStyle = MeCellStyle_itemCell;
    secondModel5.title = @"Feedback";
    secondModel5.isHiddenLine = NO;
    secondModel5. cellHeight = 48 * rectScale();
    
    MeConfigModel *secondModel6 = [[MeConfigModel alloc] init];
    secondModel6.cellType = MeCellType_userInstruction;
    secondModel6.cellStyle = MeCellStyle_itemCell;
    secondModel6.title = @"User Notice";
    secondModel6.isHiddenLine = NO;
    secondModel6. cellHeight = 48 * rectScale();
    
    MeConfigModel *secondModel7 = [[MeConfigModel alloc] init];
    secondModel7.cellType = MeCellType_privacy;
    secondModel7.cellStyle = MeCellStyle_itemCell;
    secondModel7.title = @"Privacy Settings";
    secondModel7.isHiddenLine = NO;
    secondModel7. cellHeight = 48 * rectScale();
    
    MeConfigModel *secondModel8 = [[MeConfigModel alloc] init];
    secondModel8.cellType = MeCellType_aboutUS;
    secondModel8.cellStyle = MeCellStyle_itemCell;
    secondModel8.title = @"About us";
    secondModel8. cellHeight = 48 * rectScale();
    secondModel8.isHiddenLine = YES;

    [arr addObject:secondModel3];
    [arr addObject:secondModel4];
    [arr addObject:secondModel5];
    [arr addObject:secondModel6];
    [arr addObject:secondModel7];
    [arr addObject:secondModel8];
    return arr;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSArray *arr = self.dataList[indexPath.section];
    if (arr. count > 0) {
        MeConfigModel *model = arr[indexPath.row];
        if (self. clickTool & amp; & amp; [self. clickTool respondsToSelector:@selector(jumpToControllerWithModel:)]) {
            [self.clickTool jumpToControllerWithModel:model];
        }
    }
}

- (ISMeClickTool *)clickTool {
    if (!_clickTool) {
        _clickTool = [[ISMeClickTool alloc] init];
        _clickTool.fatherVC = self;
        WEAKSELF
        _clickTool.clearCacheSucess = ^{
            [weakSelf dealWithClearCacheSucess];
        };
    }
    return _clickTool;
}

Settings page

- (NSMutableArray *)createDataList {
    NSMutableArray *arr = [[NSMutableArray alloc] init];

    if([TPUserDefault instance].userBO){
        MeConfigModel *secondModel2 = [[MeConfigModel alloc] init];
        secondModel2.cellType = MeCellType_account;
        secondModel2.cellStyle = MeCellStyle_itemCell;
        secondModel2.title = @"Account and Security";
        secondModel2. cellHeight = 48 * rectScale();
        secondModel2.isHiddenLine = NO;
        [arr addObject:secondModel2];
    }

    MeConfigModel *secondModel3 = [[MeConfigModel alloc] init];
    secondModel3.cellType = MeCellType_clearMemnory;
    secondModel3.cellStyle = MeCellStyle_itemCell;
    secondModel3.title = @"Clean cache";
    secondModel3.isHiddenLine = NO;
    NSString *cachePath = CachePath(@"");
    NSString *string = [NSString stringWithFormat:@"%.2fM",[self folderSizeAtPath:cachePath]];
    secondModel3.subTitle = string;
    secondModel3. cellHeight = 48 * rectScale();
    
    MeConfigModel *secondModel4 = [[MeConfigModel alloc] init];
    secondModel4.cellType = MeCellType_push;
    secondModel4.cellStyle = MeCellStyle_itemCell;
    secondModel4.title = @"Push Settings";
    secondModel4.isHiddenLine = NO;
    secondModel4. cellHeight = 48 * rectScale();
    
    MeConfigModel *secondModel5 = [[MeConfigModel alloc] init];
    secondModel5.cellType = MeCellType_sugess;
    secondModel5. cellStyle = MeCellStyle_itemCell;
    secondModel5.title = @"Feedback";
    secondModel5.isHiddenLine = NO;
    secondModel5. cellHeight = 48 * rectScale();
    
    MeConfigModel *secondModel6 = [[MeConfigModel alloc] init];
    secondModel6.cellType = MeCellType_userInstruction;
    secondModel6.cellStyle = MeCellStyle_itemCell;
    secondModel6.title = @"User Notice";
    secondModel6.isHiddenLine = NO;
    secondModel6. cellHeight = 48 * rectScale();
    
    MeConfigModel *secondModel7 = [[MeConfigModel alloc] init];
    secondModel7.cellType = MeCellType_privacy;
    secondModel7.cellStyle = MeCellStyle_itemCell;
    secondModel7.title = @"Privacy Settings";
    secondModel7.isHiddenLine = NO;
    secondModel7. cellHeight = 48 * rectScale();
    
    MeConfigModel *secondModel8 = [[MeConfigModel alloc] init];
    secondModel8.cellType = MeCellType_aboutUS;
    secondModel8.cellStyle = MeCellStyle_itemCell;
    secondModel8.title = @"About us";
    secondModel8. cellHeight = 48 * rectScale();
    secondModel8.isHiddenLine = YES;

    [arr addObject:secondModel3];
    [arr addObject:secondModel4];
    [arr addObject:secondModel5];
    [arr addObject:secondModel6];
    [arr addObject:secondModel7];
    [arr addObject:secondModel8];
    return arr;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    MeConfigModel *model = self.dataList[indexPath.row];
    if (self. clickTool & amp; & amp; [self. clickTool respondsToSelector:@selector(jumpToControllerWithModel:)]) {
        [self.clickTool jumpToControllerWithModel:model];
    }
}

- (ISMeClickTool *)clickTool {
    if (!_clickTool) {
        _clickTool = [[ISMeClickTool alloc] init];
        _clickTool.fatherVC = self;
        WEAKSELF
        _clickTool.clearCacheSucess = ^{
            [weakSelf dealWithClearCacheSucess];
        };
    }
    return _clickTool;
}

proxy object

@implementation ISMeClickTool

- (void)jumpToControllerWithModel:(MeConfigModel *)model {
   
   if (model. cellType == MeCellType_history) {
       NSLog(@"Read History");
       if (![TPUserDefault instance].userBO) {
           [self oneClickToLogin];
           return;
       }
       
       TPHistoryDetailViewContorller *VC = [[TPHistoryDetailViewContorller alloc]init];
       [self.fatherVC.navigationController pushViewController:VC animated:YES];

   } else if (model. cellType == MeCellType_guanzhu) {
       NSLog(@"My Downloads");
       if (![TPUserDefault instance].userBO) {
           [self oneClickToLogin];
           return;
       }
       
       TPMyAttentionViewController *vc = [[TPMyAttentionViewController alloc]init];
       [self.fatherVC.navigationController pushViewController:vc animated:YES];
   } else if (model. cellType == MeCellType_myCollection) {
       NSLog(@"My Collection");
       if (![TPUserDefault instance].userBO) {
           [self oneClickToLogin];
           return;
       }
       
       TPCollectionViewController *vc = [[TPCollectionViewController alloc]init];
       [self.fatherVC.navigationController pushViewController:vc animated:YES];
       
   }else if (model. cellType == MeCellType_pingliun) {
       NSLog(@"Comment");
       if (![TPUserDefault instance].userBO) {
           [self oneClickToLogin];
           return;
       }
       TPMyCommentViewController *comment = [[TPMyCommentViewController alloc] init];
       [self.fatherVC.navigationController pushViewController:comment animated:YES];
   }else if (model. cellType == MeCellType_xiaoxi) {
       NSLog(@"message");
       if (![TPUserDefault instance].userBO) {
           [self oneClickToLogin];
           return;
       }
       TPMessageController *message = [[TPMessageController alloc] init];
       [self.fatherVC.navigationController pushViewController:message animated:YES];
       
   } else if (model. cellType == MeCellType_account) {
       NSLog(@"account");
       if (![TPUserDefault instance].userBO) {
           [self oneClickToLogin];
           return;
       }
       AccountSecurityController *accountVC = [AccountSecurityController new];
       accountVC.isShutong = self.isShutong;
       [self.fatherVC.navigationController pushViewController:accountVC animated:YES];
       

   } else if (model. cellType == MeCellType_sugess) {
       NSLog(@"view");
       if (![TPUserDefault instance].userBO) {
           [self oneClickToLogin];
           return;
       }
       FeedbackViewController *vc = [[FeedbackViewController alloc]init];
       vc.feedbackEnterType = FeedbackMineEnterType;
       [self.fatherVC.navigationController pushViewController:vc animated:YES];
   } else if (model. cellType == MeCellType_push) {
       NSLog(@"push");
       openSystemSetting();
   } else if (model. cellType == MeCellType_clearMemnory) {
       float size = [self readCacheSize];
       if (size == 0) {
           ShowTextMessage(@"No cache");
       } else {
           NSString *titleNamme = [NSString stringWithFormat:@"You have %.1fMB cache, do you want to clear it?",size];
           [[TPUserDefault instance]showAlertViewContollerWithTitle:titleNamme message:@"" cancleName:@"cancel" sureName:@"confirm" WithSureAction:^{
               [[TPUserDefault instance] clearCache];
               ShowTextMessage([NSString stringWithFormat:@"Successfully cleaned up %.1fMB", size]);
               if(self.clearCacheSucess){
                   self. clearCacheSucess();
               }
           } cancelAction: ^{
               
           }];
           
           
       }
   } else if (model. cellType == MeCellType_privacy) {
       NSLog(@"Privacy Settings");
       PrivacySettingViewController *vc = [[PrivacySettingViewController alloc]init];
       [self.fatherVC.navigationController pushViewController:vc animated:YES];
   } else if (model. cellType == MeCellType_userInstruction) {
       NSLog(@"User Agreement");
       UserInstructionController *userInstructVC = [UserInstructionController new];
       [self.fatherVC.navigationController pushViewController:userInstructVC animated:YES];
   } else if (model. cellType == MeCellType_aboutUS) {
       NSLog(@"about us");
       AboutUsVC *aboutVC = [[AboutUsVC alloc]init];
       [self.fatherVC.navigationController pushViewController:aboutVC animated:YES];
   }
   
}

- (void) jumpToMessage {
   NSLog(@"message");
   
   if (![TPUserDefault instance].userBO) {
       [self oneClickToLogin];
       return;
   }
//
// ISMyMessageController *vc = [[ISMyMessageController alloc] init];
// [self.fatherVC.navigationController pushViewController:vc animated:YES];
}

- (void)jumpToUerHome {
   NSLog(@"personal page");
   
   if (![TPUserDefault instance].userBO) {
       [self oneClickToLogin];
       return;
   }
   
   pushToUserHome([TPUserDefault instance].userBO.userId);
}

- (void) oneClickToLogin {
   NSLog(@"one key login");
   
   __weak LoginAccelerateManager *loginManager = [LoginAccelerateManager instance];
   [loginManager LoginWithTimeout:3.0 Controller:self.fatherVC AuthorizeType:TPAuthorizeLoginType Parameter:@{@"pushLogin":@"1",@"sourceType":@"1"} AccelerateComplete:nil NormalLoginComplete:nil];
   
}

- (void)qrCodeClick{
   TPShuTongQrCodeViewController *vc = [[TPShuTongQrCodeViewController alloc]init];
   [self.fatherVC.navigationController pushViewController:vc animated:YES];
}


-(float) readCacheSize
{
   NSString *cachePath = [NSSearchPathForDirectoriesInDomains (NSCachesDirectory, NSUserDomainMask, YES) firstObject];
   return [self folderSizeAtPath:cachePath];
}

// traverse the folder to get the size of the folder, and return how many M
- (float)folderSizeAtPath:(NSString *)folderPath {
   
   NSFileManager * manager = [NSFileManager defaultManager];
   if (![manager fileExistsAtPath :folderPath]) return 0 ;
   NSEnumerator *childFilesEnumerator = [[manager subpathsAtPath :folderPath] objectEnumerator];
   NSString * fileName;
   long long folderSize = 0;
   while ((fileName = [childFilesEnumerator nextObject]) != nil ){
       //Get the full path of the file
       NSString * fileAbsolutePath = [folderPath stringByAppendingPathComponent :fileName];
       folderSize += [self fileSizeAtPath :fileAbsolutePath];
   }

   return folderSize/( 1024.0 * 1024.0);
   
}

// Calculate the size of a single file
- (long long)fileSizeAtPath:(NSString *)filePath{
   NSFileManager * manager = [NSFileManager defaultManager];
   if ([manager fileExistsAtPath :filePath]){
       return [[manager attributesOfItemAtPath :filePath error : nil] fileSize];
   }
   return 0;
}

As shown in the code above, the separation of the proxy method is realized