Anthon Santhez
Anthon Santhez

Reputation: 434

How to define a variable function and call it from an extension file in swift?

I created an extension swift file, and in that file I wrote extension UIViewController{ ... } in my project, rather than writing all lines in every view controller. Everything worked ok. Later on I created a public func(i.e myFunc), with the same name inside each of the 30 view controllers, and having different outputs. I am trying to call this common named function from the extension file, but I get an error "Value of type 'UIViewController' has no member 'myFunc'. On the extension file, how can I call this common named function which executes different outputs on each different view controller?

Extension file Code:

extension UIViewController {
    func sampleFunc {
        let viewController = self.navigationController?.visibleViewController {
        ........
        viewController.myFunc() }.    *//error: Value of type 'UIViewController?' has no member 'myFunc'*
    }
}

Note: I don't want to use like this:

if let viewController = self as? ViewController1 {viewController.myFunc()}
if let viewController = self as? ViewController2 {viewController.myFunc()}
if let ... 3,
4....30

Or maybe is there a way to check whether the function exists, and if it exists then execute command without receiving that kind of errors ?

use of unresolved identifier

or

value of type 'UIViewController?' has no member 'myFunc'

Upvotes: 0

Views: 457

Answers (2)

Sweeper
Sweeper

Reputation: 272715

The viewController variable in the extension is could be any VC, couldn't it? Not just the 30 you created. You can't guarantee that any random VC will have a method called myFunc, so you can't call it in the extension.

One way to resolve this problem is to create a protocol that your 30 VCs all implement:

protocol MyFuncable : UIViewController { // please come up with a better name
    func myFunc ()
}

This is an example of how you implement the protocol:

class ViewController: UIViewController, MyFuncable { 
    func myFunc() { 
        // do whatever you want...
        print("myFunc executed")
    }
}

Now we guarantee that everything that implements myFuncable will have a method called myFunc, so now in your extension, you can check whether the VCs are MyFuncable:

extension UIViewController {
    func sampleFunc() {
        // here is where the checking happens:
        if let viewController = self.navigationController?.visibleViewController as? MyFuncable {
            viewController.myFunc() 
        }
    }
}

Upvotes: 4

AMIT
AMIT

Reputation: 924

Try this code below.

extension UIViewController {
    func sampleFunc() {
        if let viewController = self.navigationController?.visibleViewController {
            print("Class name: \(NSStringFromClass(type(of: viewController)))")
            let anyObject = viewController as AnyObject
            if anyObject.responds(to: #selector(anyObject.myFunc)) {
                anyObject.myFunc()
            }
        }
    }
}

Upvotes: 0

Related Questions