Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Want to create a listener that detects viewWillAppear calls throughout the app

I want to have a listener of sorts that reports whenever a new UIViewController is pushed. I can achieve this by subclassing from a single class and then listening in super viewDidLoad/viewDidAppear calls. But I would still have to pass the subclass name to super.

Is there any other way to automatically detect whenever any new view appears?

Context of it is that I am working on a logging library that reports screen load time etc. I also want to listen to any button tap ever in the app at a single point.

like image 768
frigocat Avatar asked Jan 03 '23 09:01

frigocat


1 Answers

For logging purposes, you don't need to subclass or tediously add code to every UIViewController instance. Instead, swizzle the UIViewController's viewDidAppear method with your own.

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 UIViewController {

    static let classInit: Void = {
        let originalSelector = #selector(viewDidAppear(_:))
        let swizzledSelector = #selector(swizzledViewDidAppear(_:))
        swizzling(UIViewController.self, originalSelector, swizzledSelector)
    }()

    @objc func swizzledViewDidAppear(_ animated: Bool) {
        print("Add your logging logic here")
        // Call the original viewDidAppear - using the swizzledViewDidAppear signature
        swizzledViewDidAppear(animated)
    }

}

Note you'll have to kick-off the swizzle by overriding the AppDelegate's init for Swift 4.

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

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

Original credits to @efremidze and @TikhonovAlexander

like image 183
Jalakoo Avatar answered Feb 17 '23 15:02

Jalakoo