Search code examples
swiftmacoscocoamenubar

List all mounted Volumes in a Menu Bar Submenu (programmatically only)


I'm currently working on a "menu bar only" project and I need to list all mounted Volumes in a submenu in the menubar app. I figured out how to print() all mounted volumes but I need help with the submenu (without .xib or .storyboard work) This is my "listVolumes func"

    func listVolumes(sender: NSMenuItem) {
    let keys = [NSURLVolumeNameKey, NSURLVolumeIsRemovableKey, NSURLVolumeIsEjectableKey]
    let paths = NSFileManager().mountedVolumeURLsIncludingResourceValuesForKeys(keys, options: [])
    if let urls = paths {
        for url in urls {
            if let components = url.pathComponents
                where components.count > 1
                    && components[1] == "Volumes" {
                print(url)
            }
        }
    }
}

an below is my code for the "menu bar app"

    let statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(-2)

func applicationDidFinishLaunching(aNotification: NSNotification) {

    if let button = statusItem.button {
        button.image = NSImage(named: "StatusBarButtonImage")
    }
    let menu = NSMenu()

    menu.addItem(NSMenuItem(title: "Volumes", action: Selector("volumes:"), keyEquivalent: ""))
    menu.addItem(NSMenuItem.separatorItem())
    menu.addItem(NSMenuItem(title: "Help", action: Selector("help:"), keyEquivalent: ""))
    menu.addItem(NSMenuItem.separatorItem())
    menu.addItem(NSMenuItem(title: "Quit", action: Selector("terminate:"), keyEquivalent: "q"))

    statusItem.menu = menu

}

so my question is, how can I create a submenu that contains all the mounted drives (programmatically only)


Solution

  • You have to set a submenu to the volumes menu item for example

    let volumesMenuItem = NSMenuItem(title: "Volumes", action: Selector("volumes:"), keyEquivalent: "")
    menu.addItem(volumesMenuItem)
    let volumesMenu = NSMenu(title: "Volumes")
    volumesMenuItem.submenu = volumesMenu
    

    I recommend to return an array of the names from your listVolumes() function, then you can add menu items to volumesMenu assuming volumes contains the names

    for volumeName in volumes {
        volumesMenu.addItem(NSMenuItem(title: volumeName, action: Selector("selectVolume"), keyEquivalent: ""))
    }