简体   繁体   中英

Track any user interaction of an iOS App

How can I track or catch every user interaction of my iOS app? Like pressing an UIButton, UIBarButton, ... any UIControl element.

I know there are hundreds of analytics tools like Google Analytics, Flurry, Appsee and so on, but I want to save these data on my own server.

Hello @tuvok if you dont want to use Google analytics and others libraries then you have to make an API(Web service). you have to hit api on every user interaction like button pressed or anything else.

You can subclass UIApplication:

  • Create an UIApplication Subclass
  • override the sendAction(_ action: Selector, to target: Any?, from sender: Any?, for event: UIEvent?) event method, remember to call the super implementation
  • put an NSLog or other diagnostic code inside the implementation

Example, this will print a log every time an UIButton is pressed:

func sendAction(_ action: Selector, to target: Any?, from sender: Any?, for event: UIEvent?) -> Bool {
    if (sender is UIButton) {
        print("Action: \(NSStringFromSelector(action)) - \(target) - \(sender)")
    }
    return super.sendAction(action, to: target, from: sender, for: event)
}


2017-07-08 14:46:18.270 UIApplicationSubclass[94764:c07] Action: anAction: - <ViewController: 0x76790a0> - <UIRoundedRectButton: 0x767b9b0; frame = (103 66; 73 44); opaque = NO; autoresize = TM+BM; layer = <CALayer: 0x767bad0>>
2017-07-08 14:46:27.378 UIApplicationSubclass[94764:c07] Action: anAction: - <ViewController: 0x76790a0> - <UIRoundedRectButton: 0x767b9b0; frame = (103 66; 73 44); opaque = NO; autoresize = TM+BM; layer = <CALayer: 0x767bad0>>

For objective-c reference click here

found an easy solution:

1 .create an UIControl extension

private let swizzling: (AnyClass, Selector, Selector) -> () = { forClass, originalSelector, swizzledSelector in
    let originalMethod = class_getInstanceMethod(forClass, originalSelector)
    let swizzledMethod = class_getInstanceMethod(forClass, swizzledSelector)
    method_exchangeImplementations(originalMethod!, swizzledMethod!)
}

extension UIControl {

    static let classInit: Void = {
        let originalSelector = #selector(sendAction(_:to:for:))
        let swizzledSelector = #selector(swizzled_sendAction(_:to:for:))
        swizzling(UIControl.self, originalSelector, swizzledSelector)
    }()

    @objc func swizzled_sendAction(_ action: Selector, to target: Any?, for event: UIEvent?) {

        swizzled_sendAction(action, to: target, for: event)
        print("action was triggered")
    }
}
  1. init in AppDelegate:

    @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate {

     override init() { super.init() UIControl.classInit } 

example from here: https://stackoverflow.com/a/42047289/2820043

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM