MethodSwizzling 就是偷梁换柱。
使用该大神封装好的一套hook库RSWizzle。
https://github.com/rentzsch/jrswizzle
页面访问路径,友盟使用,进入页面记录下,离开页面时记录下。
以下代码直接在程序启动的时候调用
/**
通过hook viewWillAppear 和viewDidDisAppear 去计算页面的停留时间
统计每个页面的停留时长
*/
- (void)setupUMengStayTimeInViewController{
RSSwizzleInstanceMethod([UIViewController class],
@selector(viewDidAppear:),
RSSWReturnType(void),
RSSWArguments(BOOL animated),
RSSWReplacement(
{
// The following code will be used as the new implementation.
//这里的self,就是hook的原方法的类的实例。所以此处也就是UIViewController对象
NSLog(@"swizzle contentmode %@", self);
if( [self isKindOfClass:[UIViewController class]] ){
UIViewController *ctrl = (UIViewController*)self;
[AppDelegate beginLogPageViewWithCtrl:ctrl];
NSLog(@"进入页面%@",[ctrl class]);
}
// Calling original implementation.
RSSWCallOriginal(animated);
}), 0, NULL);
RSSwizzleInstanceMethod([UIViewController class],
@selector(viewWillDisappear:),
RSSWReturnType(void),
RSSWArguments(BOOL animated),
RSSWReplacement(
{
// The following code will be used as the new implementation.
//这里的self,就是hook的原方法的类的实例。所以此处也就是UIViewController对象
NSLog(@"swizzle contentmode %@", self);
if( [self isKindOfClass:[UIViewController class]] ){
UIViewController *ctrl = (UIViewController*)self;
NSLog(@"离开页面%@",[ctrl class]);
[AppDelegate endLogPageViewWithCtrl:ctrl];
}
// Calling original implementation.
RSSWCallOriginal(animated);
}), 0, NULL);
}
+ (void)beginLogPageViewWithCtrl:(UIViewController*)ctrl{
NSString *pageName = ctrl.navigationItem.title;
if( pageName == nil ){
pageName = NSStringFromClass([ctrl class]);
}
[MobClick beginLogPageView:pageName];
}
+ (void)endLogPageViewWithCtrl:(UIViewController*)ctrl{
NSString *pageName = ctrl.navigationItem.title;
if( pageName == nil ){
pageName = NSStringFromClass([ctrl class]);
}
[MobClick endLogPageView:pageName];
}
总结:都说不要滥用黑魔法,会出现意向不到的bug, 这个确实会存在。但这种页面的统计,我实在不想写个父类,然后依次去改每个类了。这种时候的使用是可以理解的。
网友评论