Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Extension - method conflicts with previous declaration with the same Objective-C selector

I am working on iOS app which is having Obj C code as well as Swift. I am migrating my existing Objective C category to swift code. But when I override existing method in swift extension, it is not compiling. Swift extension is working well for new methods but not for overriding existing methods.

Code:

extension UIViewController {


   public override func shouldAutorotate() -> Bool {
        return false
    }

    public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return UIInterfaceOrientationMask.Portrait
    }


}

Error:

 Method 'shouldAutorotate()' with Objective-C selector 'shouldAutorotate' conflicts with previous declaration with the same Objective-C selector

 Method does not override any method from its superclass

 Method 'supportedInterfaceOrientations()' with Objective-C selector 'supportedInterfaceOrientations' conflicts with previous declaration with the same Objective-C selector

Here, Am I missing anything?

I am using Xcode 7.3.1 and Swift 2.x

EDIT:

From below Answers, I got to know that We cant change behaviour of existing method of class at runtime in Swift extension like in Objective C Categories. Here I should make a base class which will override method and I should use all my ViewControllers as child classes from new base class as parent.

But in my case, I want to change behaviour of all "shouldAutorotate" methods including 3rd party frameworks UIViewController. In above case I cant force all third party frameworks UIviewControllers to become subclass of my base class. In Objective C i could achieve this.

like image 274
Swapnil Avatar asked Jun 08 '16 15:06

Swapnil


1 Answers

Swift extensions aren't to be used to override methods declared in the class they're extending – especially for Objective-C classes, that's very much like providing two definitions of the same method in the same class. Imagine seeing a class that looked like:

class UIViewController : UIResponder {
    public func shouldAutorotate() -> Bool {
        return true
    }
    public func shouldAutorotate() -> Bool {
        return false
    }
}

Which one wins? That's the conflict you're being warned about.

If you need to override methods for a view controller of yours, you'll need to do that in a subclass, not an extension.

Ninja edit: this may have been possible to do in Objective-C, but was a programming error there. If a category duplicates a method from a main class, which definition gets used is undefined. See this SO post and the backing Apple documentation.

like image 168
Tim Avatar answered Nov 14 '22 23:11

Tim