Vadim Nikolaev
Vadim Nikolaev

Reputation: 2132

Swizzling CocoaTouch class in Swift 3.1

I use Swift 3.1 in XCode 8.3 and see that warning:

Method 'initialize()' defines Objective-C class method 'initialize', which is not guaranteed to be invoked by Swift and will be disallowed in future versions

I use Swizzling CocoaTouch class and have an issue with that part:

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)")
    } 
 }

How to rewrite that part of the code?

open override class func initialize()

for fix new warning?

I saw that link, but I don't understand how to use info in my code.

Upvotes: 4

Views: 627

Answers (1)

isseium
isseium

Reputation: 625

I had same problem and fix it.

My Solution

1. Change swizzling() method to public from private

public let swizzling: (AnyClass, Selector, Selector) -> () = { forClass, originalSelector, swizzledSelector in
    let originalMethod = class_getInstanceMethod(forClass, originalSelector)
    let swizzledMethod = class_getInstanceMethod(forClass, swizzledSelector)
    method_exchangeImplementations(originalMethod, swizzledMethod)
}

2. Remove initialize() method at extension UIViewController

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

3. Add swizzling() at AppDelegate::didFinishLaunchingWithOptions

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

    // some code

    swizzling(UIViewController.self)

    return true
}

This is simply/easy solution. (this is not Elegant)

If you want to get more information, please see this: Swift 3.1 deprecates initialize(). How can I achieve the same thing?

Upvotes: 3

Related Questions