Sunday, November 5, 2017

Swift 4 Method Swizzling (Part 2/2)

In the Swift 4 Method Swizzling (Part 1/2) post, We have seen the approach of using Base classes for a notification needed 
whenever a view appears, Which resulted in code redundancy.

In this post, Let’s see how that can be solved using Method Swizzling.

Take an extension of UIViewController and apply swizzling for it’s viewWillAppear method.

--------------------------------------------------------------------------

extension UIViewController {

    func newViewWillAppear(_ animated: Bool) {
        self.newViewWillAppear(animated) //Incase we need to override this method
        print("Display Notification!")
    }
    
    static func swizzleViewWillAppear() {
         //Make sure This isn't a subclass of UIViewController, So that It applies to all UIViewController childs
        if self != UIViewController.self {
            return
        }
        let _: () = {
            let originalSelector = #selector(UIViewController.viewWillAppear(_:))
            let swizzledSelector = #selector(UIViewController.newViewWillAppear(_:))
            let originalMethod = class_getInstanceMethod(self, originalSelector)
            let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)
            method_exchangeImplementations(originalMethod!, swizzledMethod!);
        }()
    }    
}

--------------------------------------------------------------------------

Here, I am swapping, viewWillAppear with my custom Method newViewWillAppear using method_exchangeImplementations, Which is from ObjectiveC runtime.

--------------------------------------------------------------------------
method_exchangeImplementations(Method _Nonnull m1, Method _Nonnull m2) 
--------------------------------------------------------------------------

At run time, calling viewWillAppear on UIViewController calls newViewWillAppear method, 
Where we will have the notification logic.

Now, In the child classes of UIViewControllers, super.ViewWillAppear, Calls the newViewWillAppear.

The beauty here is, The same will get called for UITableViewController and UINavigationController also as they are also extended from UIViewController.

Thus, Using Method Swizzling, There will not be any code redundancy. 

Unlike in Swift3x, In swift 4, We can not write this swizzling the initialise method, And we can call it in AppDelegate.

--------------------------------------------------------------------------

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        // Override point for customization after application launch.

        UIViewController.swizzleViewWillAppear()

        return true
    }

--------------------------------------------------------------------------

So, Whenever app launches, This swizzling applies and stays.

Hope this post is useful. Feel free to comment incase of any queries.




2 comments:


  1. This article is very much helpful and i hope this will be an useful information for the needed one.Keep on updating these kinds of informative things ios online training hyderabad

    ReplyDelete
  2. This is a wonderful blog post. Thanks for sharing the information. For more details kindly visit us at Swift App Development Company in India. Call us: +91-7314236251 or mail us at sales@samosys.com

    ReplyDelete