You need a non-weak reference for the item's target.
try this:
// Define this in your class.
static let itemTarget = CustomToolbarButton(itemIdentifier: "myButton")
// and use it when setting the target in the constructor.
self.target = CustomToolbarButton.itemTarget
From docs.swift.org
"A weak reference is a reference that does not keep a strong hold on the instance it refers to, and so does not stop ARC from disposing of the referenced instance."
If all references to the instance are weak, the item is created and released automatically. You need at least one non-weak reference to keep hold of the instance.
Recommended Reading:
https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html
Also, like you stated, the @objc directive is needed in the action function.
Here are some helpful links.
'#selector' refers to a method that is not exposed to Objective-C
'#selector' refers to a method that is not exposed to Objective-C
See Selector Expression
https://docs.swift.org/swift-book/ReferenceManual/Expressions.html
Lastly here is a working example on Xcode 10.3 and Swift 5:
// Created by Juan Miguel Pallares Numa on 9/12/19.
// Copyright © 2019 Juan Miguel Pallares Numa. All rights reserved.
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
// Strong reference.
var myWindowController = WindowController()
func applicationDidFinishLaunching(_ aNotification: Notification) {
myWindowController.makeWindowKeyAndOrderFront()
}
}
import Cocoa
class ToolbarController: NSObject, NSToolbarDelegate {
let identifiers = [NSToolbarItem.Identifier("myIdentifier")]
let toolbar = NSToolbar()
let toolbarItem: NSToolbarItem
override init() {
toolbarItem = NSToolbarItem(itemIdentifier: identifiers[0])
super.init()
toolbar.delegate = self
toolbarItem.label = "Print My Console Message"
toolbarItem.target = self
toolbarItem.action = #selector(
ToolbarController.toolbarAction(_:))
toolbarItem.image = NSImage(named: NSImage.applicationIconName)!
}
@objc func toolbarAction(_ sender: Any?) {
print("Hello world")
}
func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return identifiers
}
func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return identifiers
}
func toolbarSelectableItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return identifiers
}
func toolbar(_ toolbar: NSToolbar,
itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier,
willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
return toolbarItem
}
}
import Cocoa
class WindowController: NSWindowController {
var toolbarController = ToolbarController()
convenience init() {
let window = NSWindow(
contentViewController: ViewController())
self.init(window: window)
window.toolbar = toolbarController.toolbar
}
func makeWindowKeyAndOrderFront() {
window?.makeKeyAndOrderFront(nil)
}
}
import Cocoa
class ViewController: NSViewController {
override func loadView() {
view = NSView(frame: NSRect(x: 0, y: 0, width: 400, height: 300))
}
}