iOS逆向:去除【系统更新】的弹窗

背景:

  • 可能你会因为手机容量太小不想更新系统,或者单纯不想更新系统导致手机变卡。
  • 那么你应该是经常被系统更新提示的弹窗所烦恼,系统基本每天都会弹窗一次。
  • 所以这里通过逆向方式去hook系统弹窗,去除【系统更新】的提示。

主要逻辑:

  • 在viewWillAppear: 调用弹窗的_setHidden:
  • 在viewDidAppear: 触发它的cancelAction的block

缺陷:

  • 判断是否是【系统更新】弹窗是通过字符串匹配,且暂时只匹配了中文
  • 暂时探索更优方法中...

扩展:

  • 如果你的App想要实现自动化测试,势必要处理因为弹窗导致测试被中断问题,可以参考本文方案

/// Tweak.xm

#import 

@interface LincMethodList

- (id)title;
- (id)cancelAction;
- (id)actions;
- (id)firstObject;
- (void)_setHidden:(BOOL)arg1;
- (id)currentIsNeedHookAlert;

@end

%hook _SBAlertController

%new
- (id)currentIsNeedHookAlert
{
    id vc = self;
    id action = [vc cancelAction];
    if (action == nil) {
        action = [[vc actions] firstObject];
    }

    if (action && [[vc title] isKindOfClass:%c(NSString)] && [[vc title] isEqualToString:@"\xe8\xbd\xaf\xe4\xbb\xb6\xe6\x9b\xb4\xe6\x96\xb0"]) {
        return action;
    }

    return nil;
}

/// 将要出现到屏幕上时,将它隐藏
/// 这里如果放到viewDidAppear,还是能看到这个Alert
- (void)viewWillAppear:(BOOL)arg1
{
    %orig;

    id vc = self;
    if ([vc currentIsNeedHookAlert]) {
        [vc _setHidden:YES];
    }
}

/// 已经出现到屏幕上后,触发它的cancelAction的block,系统会将该Alert移除
/// 为什么不放在viewWillAppear:
/// 如果遇到需要同时弹出多个Alert这种场景,系统会维护一个Alert队列,只有用户点击了前一个Alert 下一个Alert的viewDidAppear才会触发,但是,每个Alert的viewWillAppear却在加入队列时就已经触发了。
- (void)viewDidAppear:(BOOL)arg1
{
    %orig;

    id vc = self;
    id action = [vc currentIsNeedHookAlert];
    if (action && [vc respondsToSelector:@selector(_dismissAnimated:triggeringAction:)]) {
        [vc performSelector:@selector(_dismissAnimated:triggeringAction:) withObject:@(NO) withObject:action];
    }
}

%end

/// 顺便去除一下所有推送的数字角标
%hook SBIconParallaxBadgeView

- (id)init
{
    return nil;
}

%end

你可能感兴趣的:(iOS逆向:去除【系统更新】的弹窗)