Method Swizzling in Swift

Table of Contents

  • Problems?
  • What is method swizziling?
  • Swizzling CocoaTouch class
  • Swizzling custom Swift class
  • Note
  • References

Problems?

If you meet one of these situations, how will you handle?

  • Firebase SDK only provides you a function named "showLoginView()" to present a LoginViewController. The problem is all of view controllers in your app use a custom background color? So how can we set background color for LoginViewController?
  • Firebase SDK saves value to UserDataDefault, but you expect that all keys must have a prefix, for example is "FPT". How can you do this?

Method swizzling comes to rescue

Defination

So what is method swizzling?

Method swizzling is the process of changing the implementation of an existing selector at runtime.

Speak in a easy-to-understand way, method swizzling acts like swap(a, b) function. It will takes implementation of function 1 and function 2 and swap.

Swizzling

Use swizzling to solve the problem:

So with method swizzling, we can change the implementation of viewDidLoad in LoginViewController to our custom implementation that calls change backgroundColor.

Swizzling CocoaTouch class

To swizzle, you just need to follow some steps:

  1. Create a new method with your custom implementation.
  2. Get default method selector reference.
  3. Get new method selector reference.
  4. Use objective-C runtime to switch the selectors.

Let’s swizzle:

First, create a demo view controller and create new method with your custom implementation.

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        debugPrint("Call default view did load")
    }
}

extension UIViewController {
    // 1 
    @objc func viewDidLoadSwizzlingMethod() {
        // 2 
        self.viewDidLoadSwizzlingMethod()
        
        // 3 
        debugPrint("Swizzleeee. Call NEW view did load ")
        view.backgroundColor = .yellow
    }
}

  1. Create new method with custom implementation
  2. If you add this line, it will call new implementation first, then call default implementation. If. you don’t add this line, it will call new implentation only.
  3. Your custom implementation

Next, create a function where the swizzle takes place.

extension UIViewController {
...
     static func startSwizzlingViewDidLoad() {
        // 1
        let defaultSelector = #selector(viewDidLoad)
        let newSelector = #selector(viewDidLoadSwizzlingMethod)

        // 2
        let defaultInstace = class_getInstanceMethod(UIViewController.self, defaultSelector)
        let newInstance = class_getInstanceMethod(UIViewController.self, newSelector)
        
        // 3
        if let instance1 = defaultInstace, let instance2 = newInstance {
            debugPrint("Swizzlle for all view controller success")
            method_exchangeImplementations(instance1, instance2)
        }
    }
}
  1. Create 2 selectors of default method and new method.
  2. Create 2 references of 2 selectors by using class_getInstanceMethod.
  3. Use Objective-C runtime to “swaps implementation” of 2 selectors.

The final step is call the function startSwizzlingViewDidLoad. We must swizzle before the viewController call it’s default viewDidLoad.
Here, I will swizzle at AppDelegate to make all ViewControllers in apps change backgroundColor to yellow.

class AppDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        UIViewController.startSwizzlingViewDidLoad()
        return true
    }

    ...
}

As you can see, all of our view controllers will be set backgroundColor to yellow color.

Swizzling custom Swift class

To use method swizzling with your Swift classes, you just need to do:

  • The methods you want to swizzle must have the dynamic attribute.
  • Flow the steps like swizzle CocoaTouch class
class GST {
    
    @objc dynamic func workFromHome() {
        print("Working...")
    }
    
    @objc dynamic func swizzleWorkFromHome() {
        print("Playing from home...")
    }
    
    static func startSwizzling() {
        let defaultInstance = class_getInstanceMethod(GST.self, #selector(GST.workFromHome))
        let newInstance = class_getInstanceMethod(GST.self, #selector(GST.swizzleWorkFromHome))
        
        if let instance1 = defaultInstance, let instance2 = newInstance {
            method_exchangeImplementations(instance1, instance2)
        }
    }
}

And the results:

Note

  1. If you swizzle multiple times default method, that default method will have the implementation of the lastest swizzle method.

Example:

  • You swizzle viewDidLoad with your custom method in your AppDelegate.
  • Firebase swizzle viewDidLoad with its custom method when FirebaseSDK init in your app => after AppDelegate.
  • When a ViewController init => It will takes the implementation of Firebase’s custom method instead of your, because Firebase swizzle after you swizzle.
  1. If you are shipping a framework which is used by hundreds of apps, better not to use swizzling in this case. If you must use swizzling, you should added it to the framework’s document.

References:


Posted

in

,

by

Tags:

Comments

16 responses to “Method Swizzling in Swift”

  1. ソニー損保 死亡保険 Avatar

    For homeowners and traders, this wave of improvement presents promising prospects for property appreciation and value development, alongside access to fashionable amenities and an enhanced high quality of life.

  2. さいたま市 地下鉄 計画 Avatar

    For example, changing to a Roth IRA or taking measures to verify you’re being tax efficient.

  3. 春 むくみ Avatar

    G4007466 Flight Sergeant Patrick Conleth McCann.

  4. パソコン資格就職有利 Avatar

    The place does the bear scratch or chunk most often?

  5. 砂漠の砂はどこから Avatar

    Traditionally, the Mongols lived as nomads; nevertheless, leaders akin to Genghis Khan acknowledged that a profitable empire would have to be constructed on totally different principles.

  6. ハリーポッター 呪文一覧 Avatar

    You’ve most likely performed the popular card recreation not less than once in your life, however did you know that there’s a web-based clone of Playing cards In opposition to Humanity as nicely?

  7. すごい 熊本弁 Avatar

    Motor Life stated, “The Dodge sticks to the road like a flying bug on a windshield.” The mixture of performance and handling paid off with an excellent exhibiting within the 1956 NASCAR season.

  8. 日経新聞 購読 朝刊のみ Avatar

    Choose timeless, gender-impartial colors you’ll be able to pair easily with different tones (teal green goes as effectively with lilac as it does with navy blue), and mix in new patterns as kids grow.

  9. 千葉美容専門学校通信 Avatar

    Moreover, alcohol might not be consumed in public on the campus.

  10. sbi-sbi・v・米国高配当株式インデックス・ファンド Avatar

    In 1965, the Chevrolet Impala bought to the tune of more than 1 million items.

  11. 雇用保険料 対象 Avatar

    I unlocked the padlock and had a quick look in the chicken’s nest.

  12. 保険 代理 店 儲かる Avatar

    Wolf’s office reported $192 million has been offered through grants to greater than 10,000 companies.

  13. 秘書の品格 掲示板 Avatar

    The 1961 Lincoln Continental that carried JFK and his spouse the day he was assassinated was named SS-100-X.

  14. 最近どうですか 敬語 Avatar

    You can also make a changing desk out of a waist-high chest of drawers, but make certain you add a top with a low guardrail as well as a waterproof pad.

  15. 奈良 パチンコ 掲示板 Avatar

    This was authorized by all events.

  16. かんたん 決済 まとめ て Avatar

    1990 Residents & Southern National Bank Sovran Financial Corp.

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: