0

My question is not about how to swizzle, but rather what is happening in this particular code snippet:

private let swizzling: (UIViewController.Type) -> () = { viewController in

    let originalSelector = #selector(viewController.viewWillAppear(_:))
    let swizzledSelector = #selector(viewController.proj_viewWillAppear(animated:))

    let originalMethod = class_getInstanceMethod(viewController, originalSelector)
    let swizzledMethod = class_getInstanceMethod(viewController, swizzledSelector)

    method_exchangeImplementations(originalMethod, swizzledMethod) }

extension UIViewController {

    open override class func initialize() {
        // make sure this isn't a subclass
        guard self === UIViewController.self else { return }
        swizzling(self)
    }

    // MARK: - Method Swizzling

    func proj_viewWillAppear(animated: Bool) {
        self.proj_viewWillAppear(animated: animated)

        let viewControllerName = NSStringFromClass(type(of: self))
        print("viewWillAppear: \(viewControllerName)")
    } 
 }

This code sniper is from here: Swizzling CocoaTouch class

The question I have is around the following line of code:

// make sure this isn't a subclass
guard self === UIViewController.self else { return }

Why do we need to check if it isn't a subclass of UIViewController? My scenario is I want to send analytics data with view name to Omniture (on ever viewWillAppear). If I do the check, the swizzling never works, yet when I comment this line out, I get my desired result, and every view controller sends data.

mike.tihonchik
  • 6,855
  • 3
  • 32
  • 47
  • 1
    Then comment it out. Your needs are different from the needs of the code that you used as a model. Unclear what the question is, since you seem already to know the answer! – matt Nov 28 '17 at 18:16
  • @matt it seems that all the swift examples i looked at have this line in them, so there is some significance to that. That is what I am trying to understand – mike.tihonchik Nov 29 '17 at 15:14
  • I believe otherwise all UIViewController viewWillAppear will be swizzled regardless of the subclass in question... although I do not understand why this would be the case. Although I am not sure that this works with Swift 4 – kos Feb 16 '18 at 19:55

1 Answers1

2

The examples you've looked at seem to come from the days when this was done in the class initialize method, where you have to make that check or you can end up running the same code multiple times (when a subclass is used for the first time), which results in your swizzling an already swizzled method.

But the initialize method is no longer permitted in Swift, so that line doesn't apply.

matt
  • 515,959
  • 87
  • 875
  • 1,141