如何记录IOS中的每个用户交互
问题描述:
我想通过NSLog记录每个用户在IOS上的交互,然后可能添加文件名,方法名称和行号。如何记录IOS中的每个用户交互
通常我希望看到这样的事情:
UI Front-most view controller: MYViewController (no title)
Interaction Action [MyViewController showMenu] by sender UIBarButtonItem
这可能使用的Objective-C。我不想更改每个文件,但宁愿有一些全局方法被调用。我更喜欢在ApplicationDelegate类中执行此操作。
答
你有什么理解错误。 UIBarButtonItem
从不是发件人,因为它的类是NSObject
而不是UIView
。 UIBarButtonItem
不能接收触摸,当我们点击一个酒吧项目时接收触摸是一个UINavigationButton
(私人类)。
如果您希望在用户点击视图时记录每次用户交互,我为您提供了一个解决方案。
- 创建一个
UIWindow
(调用CustomWindow)的子类。 - 覆盖
sendEvent
方法UIWindow
捕捉用户交互,检查并记录里面的交互。 -
didFinishLaunchingWithOptions
AppDelegate
的方法,用一个窗口替换默认window
类型为CustomWindow
。
这是我CustomWindow
登录与UIControl
类的控制事件UIControlEventTouchUpInSide
用户交互。
@implementation CustomWindow
- (void)sendEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
switch ([touch phase]) {
case UITouchPhaseBegan:
{
NSLog(@"Touch Began");
}
break;
case UITouchPhaseMoved:
NSLog(@"Touch Move");
break;
case UITouchPhaseEnded:
{
NSLog(@"Touch End");
// Check if touch ends inside view (UIControlEventTouchUpInSide)
if (CGRectContainsPoint(CGRectMake(0, 0, touch.view.frame.size.width, touch.view.frame.size.height), [touch locationInView:touch.view])) {
// Only log info of UIControl objects
if ([touch.view isKindOfClass:[UIControl class]]) {
[self logViewInfo:(UIControl *)touch.view];
}
}
}
break;
case UITouchPhaseCancelled:
NSLog(@"Touch Cancelled");
break;
default:
break;
}
[super sendEvent:event];
}
- (void)logViewInfo:(UIControl *)clickedButton {
NSString *frontMostViewcontrollerClassName = NSStringFromClass(self.topViewController.class);
NSString *targetClassName = NSStringFromClass([[clickedButton.allTargets anyObject] class]);
NSString *selectorName =[[clickedButton actionsForTarget:[clickedButton.allTargets anyObject] forControlEvent:UIControlEventTouchUpInside] firstObject];
NSString *senderClassName = NSStringFromClass(clickedButton.class);
NSLog(@"UI Front-most view controller: %@\nInteraction Action [%@ %@] by sender %@ control event UIControlEventTouchUpInSide", frontMostViewcontrollerClassName, targetClassName, selectorName, senderClassName);
}
- (UIViewController*)topViewController {
return [self topViewControllerWithRootViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
}
- (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)viewController {
if ([viewController isKindOfClass:[UITabBarController class]]) {
UITabBarController* tabBarController = (UITabBarController*)viewController;
return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
} else if ([viewController isKindOfClass:[UINavigationController class]]) {
UINavigationController* navContObj = (UINavigationController*)viewController;
return [self topViewControllerWithRootViewController:navContObj.visibleViewController];
} else if (viewController.presentedViewController && !viewController.presentedViewController.isBeingDismissed) {
UIViewController* presentedViewController = viewController.presentedViewController;
return [self topViewControllerWithRootViewController:presentedViewController];
}
else {
for (UIView *view in [viewController.view subviews])
{
id subViewController = [view nextResponder];
if (subViewController && [subViewController isKindOfClass:[UIViewController class]])
{
if ([(UIViewController *)subViewController presentedViewController] && ![subViewController presentedViewController].isBeingDismissed) {
return [self topViewControllerWithRootViewController:[(UIViewController *)subViewController presentedViewController]];
}
}
}
return viewController;
}
}
更多的细节,你可以检查我的演示回购here
嗨@trungduc,感谢您的帮助 - 我将尽快尝试它。 – Wayne