Aspects https://github.com/steipete/Aspects
常用的viewDidLoad 拦截添加统计事件需求很多,因为不需要改变原本viewDidLoad事件,介绍一下另两个需求.
- 拦截修改次方法,
[UIImage imageNamed:@"ax_icon_weixin"]
返回
[UIImage imageNamed:@"chongshe"]
注意 imageNamed是+方法,所以需要用object_getClass(UIImage.class)
NSError *error;
[object_getClass(UIImage.class) aspect_hookSelector:@selector(imageNamed:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> aspectInfo,NSString *imageNamed) {
NSInvocation *invocation = aspectInfo.originalInvocation;
if ([aspectInfo.arguments.firstObject isEqualToString:@"ax_icon_weixin"]) {
id img= nil;
img= [UIImage imageNamed:@"chongshe"];
[invocation setReturnValue:&img];
NSLog(@"img %@",img);
}
} error:&error];
NSLog(@"ax_imageNamed error== %@",error);
- 在修改app icon时候,取消弹窗代码,用Aspects 实现
- (void)setIconname:(NSString *)name {
UIApplication *appli = [UIApplication sharedApplication];
//判断系统是否支持切换icon
if (@available(iOS 10.3, *)) {
if ([appli supportsAlternateIcons]) {
//切换icon
[appli setAlternateIconName:name completionHandler:^(NSError * _Nullable error) {
if (error) {
NSLog(@"error==> %@",error.localizedDescription);
}else{
NSLog(@"done!!!");
}
}];
}
} else {
// Fallback on earlier versions
}
}
自定义拦截方法
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Method presentM = class_getInstanceMethod(self.class, @selector(presentViewController:animated:completion:));
Method presentSwizzlingM = class_getInstanceMethod(self.class, @selector(dy_presentViewController:animated:completion:));
// 交换方法实现
method_exchangeImplementations(presentM, presentSwizzlingM);
});
- (void)dy_presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
if ([viewControllerToPresent isKindOfClass:[UIAlertController class]]) {
NSLog(@"title : %@",((UIAlertController *)viewControllerToPresent).title);
NSLog(@"message : %@",((UIAlertController *)viewControllerToPresent).message);
UIAlertController *alertController = (UIAlertController *)viewControllerToPresent;
if (alertController.title == nil && alertController.message == nil) {
return;
} else {
[self dy_presentViewController:viewControllerToPresent animated:flag completion:completion];
return;
}
}
[self dy_presentViewController:viewControllerToPresent animated:flag completion:completion];
}
用Aspects 实现
/// usingBlock: 第一个参数 调用对象,第二个是方法的第一次参数
[UIViewController aspect_hookSelector:@selector(presentViewController:animated:completion:) withOptions:AspectPositionInstead usingBlock:^(id<AspectInfo> aspectInfo,UIViewController *presentViewController) {
/// aspectInfo.arguments.firstObject 就是 presentViewController
if (![presentViewController isKindOfClass:[UIAlertController class]]) {
[aspectInfo.originalInvocation invoke];
}else{
UIAlertController *alertController = (UIAlertController *)presentViewController;
/// 这里用 == nil ,不要用length==0,业务需求不一样
if (alertController.title != nil || alertController.message != nil) {
[aspectInfo.originalInvocation invoke];
}
}
} error:nil];
网友评论