Issue #568
Code
Swizzle viewDidAppear
import UIKit
var mapping: [String: (UIViewController) -> Void] = [:]
var hasSwizzled = false
public func track<T: UIViewController>(_ type: T.Type, block: @escaping (T) -> Void) {
let original = #selector(UIViewController.viewDidAppear(_:))
let swizled = #selector(UIViewController.trackers_viewDidAppear(_:))
if !hasSwizzled {
swizzle(kClass: UIViewController.self, originalSelector: original, swizzledSelector: swizled)
hasSwizzled = true
}
mapping[NSStringFromClass(type)] = { controller in
if let controller = controller as? T {
block(controller)
}
}
}
extension UIViewController {
func trackers_viewDidAppear(_ animated: Bool) {
trackers_viewDidAppear(animated)
let string = NSStringFromClass(type(of: self))
mapping[string]?(self)
}
}
func swizzle(kClass: AnyClass, originalSelector: Selector, swizzledSelector: Selector) {
let originalMethod = class_getInstanceMethod(kClass, originalSelector)
let swizzledMethod = class_getInstanceMethod(kClass, swizzledSelector)
let didAddMethod = class_addMethod(kClass, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
if didAddMethod {
class_replaceMethod(kClass, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
} else {
method_exchangeImplementations(originalMethod, swizzledMethod)
}
}
Track in a declarative way
track(ListController.self) {
print("list controller has appeared")
}
track(DetailController.self) {
print("detail controller has appeared")
}
track(CouponController.self) { controller in
print("coupon controller has appeared with code \(controller.coupon.code)")
}