John Griffiths John Griffiths - 5 months ago 27
Swift Question

Delegates in OSX with Swift

i'm trying to get delegates working for an OSX app with Swift.

import Cocoa

class loginViewController: NSViewController {
weak var delegate: recordViewControllerDelegate?

override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
delegate?.trySomething()
self.delegate?.trySomething()
self.delegate?.testPrint("hello, is it me your looking for")
}
}

protocol recordViewControllerDelegate: class {
func testPrint(val: String)
func trySomething()
}

class recordViewController: NSViewController, recordViewControllerDelegate {

func testPrint(val: String) {
print(val)
}

func trySomething() {
print("aaa")
}
}


Everything looks right but testPrint & trySomething never get called, added breakpoints but nothing happens.

Any ideas what i'm missing?

Driving me round the bend...

Answer

Because your self.delegate is nil right?, so you should assign an object first. Try it like this, here is code from my AppDelegate.swift Cocoa demo project:

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet weak var window: NSWindow!

    func applicationDidFinishLaunching(aNotification: NSNotification) {
        //This is not a good practice to call viewDidLoad directly
        //Its just a demonstration of quick way to call `recordViewControllerDelegate` protocol functions
        let vc = loginViewController()
        vc.viewDidLoad()
    }
}

//MARK:- login VC
class loginViewController: NSViewController {
    weak var delegate: recordViewControllerDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()

        let recVC = recordViewController()
        self.delegate = recVC

        delegate?.trySomething()
        self.delegate?.trySomething()
        self.delegate?.testPrint("hello, is it me your looking for")
    }
}

protocol recordViewControllerDelegate: class {
    func testPrint(val: String)
    func trySomething()
}

class recordViewController: NSViewController, recordViewControllerDelegate {

    func testPrint(val: String) {
        print(val)
    }

    func trySomething() {
        print("aaa")
    }
}

Everything works fine, I can see printed logs. Please note that in my case I'm calling viewDidLoad function directly - just to show you how delegate pattern works. Apple don't recommend to call it directly. The right way is to present view controller and viewDidLoad function will be called by OS X SDK APIs.