――I thought about various patterns when implementing common processing on iOS, so I will summarize them. This time, let's focus on method swizzling.
Xcode 12.3
Build version 12C33
Apple Swift version 5.3.2 (swiftlang-1200.0.45 clang-1200.0.32.28)
Target: x86_64-apple-darwin19.6.0
--method swizzling is a function to replace the processing of existing methods. --Can be used for all Objective-C classes. --Can be implemented without inheriting common processing
--I summarized the difference between inheritance in class and implementation in method swizzling.
| ⭕️ | ❌ | |
|---|---|---|
| method swizzling | The processing is reflected in the replaced class | Since it is difficult to see the range of influence, it is difficult to deal with problems when they occur. | 
| Class inheritance | It is easy to control because the process is executed only by the inherited class. | Because all the classes that need to be implemented need to be rewritten | 
――You can see that there are advantages and disadvantages to the implementation method. You need to think carefully about how to use it.
kickstater --Used for processing that reflects ViewModel binding and style
--If you replace the implementation of viewWillAppear and use Firebase etc., you can easily implement the process of sending screen display events.
import ObjectiveC
import UIKit
private func swizzle(_ vc: UIViewController.Type) {
  [
    (#selector(vc.viewWillAppear(_:)), #selector(vc.hoge_viewWillAppear(_:)))
  ]
  .forEach { original, swizzled in
    guard let originalMethod = class_getInstanceMethod(vc, original),
      let swizzledMethod = class_getInstanceMethod(vc, swizzled) else { return }
    let didAddViewDidLoadMethod = class_addMethod(
      vc,
      original,
      method_getImplementation(swizzledMethod),
      method_getTypeEncoding(swizzledMethod)
    )
    if didAddViewDidLoadMethod {
      class_replaceMethod(
        vc,
        swizzled,
        method_getImplementation(originalMethod),
        method_getTypeEncoding(originalMethod)
      )
    } else {
      method_exchangeImplementations(originalMethod, swizzledMethod)
    }
  }
}
private var hasSwizzled = false
extension UIViewController {
  public final class func doBadSwizzleStuff() {
    guard !hasSwizzled else { return }
    hasSwizzled = true
    swizzle(self)
  }
  @objc internal func hoge_viewWillAppear(_ animated: Bool) {
    self.hoge_viewWillAppear(animated)
    let instanceType = type(of: self)
    let name = String(reflecting: instanceType)
    print(name)
  }
}
--method swizzling is convenient, but you need to know how to use it and use it.