How to call function in NSViewController?

class CustViewController: NSViewController {
@IBOutlet weak var tableView: NSTableView!
@IBOutlet weak var statusLabel: NSTextField!
fileprivate var selectedOptionFromMenu = ""

@objc var contacts:[Person] = []
@objc var backUpContacts:[Person] = []
@IBAction func printCustomers(_ sender: Any?) {

I would like to call the printCustomers function in the CustViewController from another class (NSWindowController). How is this coded in the NSWindowController class?

I tried the following:

let printAction = CustViewController.printCustomers(<#T##self: CustViewController##CustViewController#> )

but don't know how to code argument in this and this may be not be the way to do this?

Answered by Claude31 in 723051022

I thought of it after posting the answer.

In fact, IBAction is an instance func, not a class one.

So you need to call on an instance.

At least 2 ways:

  • keep a reference of the CustViewController controller(myController), and just call
let printAction = myController.printCustomers(self)
  • create an instance on which to call
let printAction = CustViewController().printCustomers(self)

it will compile but this may not work as expected if IBAction uses some CustViewController properties

Other patterns are:

  • use delegation (that may be the cleanest way)
  • send notification for the second VC to CustViewController

Hope that helps better.

I would try (but did not check yet):

let printAction = CustViewController.printCustomers(self)

Thanks for the reply!

I tried it and I get the following:

let printAction CustViewController.printCustomers(self) Instance member 'printCustomers' cannot be used on type 'CustViewController': did you mean to use a value of this type instead?

The window controller I am referring to is the main window where as the view controller is from a separate/different window controller/view controller. My objective is to have a main printer control action which would control which printout would be generated when a CMD-P is pressed.

One thing from another post mentioned I would need an instance just with contentViewController. Not sure how to code this as well?

Accepted Answer

I thought of it after posting the answer.

In fact, IBAction is an instance func, not a class one.

So you need to call on an instance.

At least 2 ways:

  • keep a reference of the CustViewController controller(myController), and just call
let printAction = myController.printCustomers(self)
  • create an instance on which to call
let printAction = CustViewController().printCustomers(self)

it will compile but this may not work as expected if IBAction uses some CustViewController properties

Other patterns are:

  • use delegation (that may be the cleanest way)
  • send notification for the second VC to CustViewController

Hope that helps better.

You are right it compiled fine with the reference and creating and instance, but did throw an exception due to the IBAction used some CustViewController properties.

So, using notification I was able to get it working.

Also, why do you think the delegation may be the cleanest way?

Thanks for the help.

Notification is great, but assumes that the receiving controller is loaded when notification is sent.

And delegation (even though a bit more complex to set up) is exactly for this: VC2 delegates to VC1 the action to execute. And you call directly the func, not through a message to interpret. But that's a personal preference.

How to call function in NSViewController?
 
 
Q