Aspects https://github.com/steipete/Aspects
常用的viewDidLoad 攔截添加統(tǒng)計(jì)事件需求很多,因?yàn)椴恍枰淖冊(cè)緑iewDidLoad事件,介紹一下另兩個(gè)需求.
- 攔截修改次方法,
[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時(shí)候,取消彈窗代碼,用Aspects 實(shí)現(xiàn)
- (void)setIconname:(NSString *)name {
UIApplication *appli = [UIApplication sharedApplication];
//判斷系統(tǒng)是否支持切換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:));
// 交換方法實(shí)現(xiàn)
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 實(shí)現(xiàn)
/// usingBlock: 第一個(gè)參數(shù) 調(diào)用對(duì)象,第二個(gè)是方法的第一次參數(shù)
[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,業(yè)務(wù)需求不一樣
if (alertController.title != nil || alertController.message != nil) {
[aspectInfo.originalInvocation invoke];
}
}
} error:nil];