Illegal NSComboBox Data source Swift 5 Storyboard

I have a combobox in a View Controller that I am trying to populate using an enum. I did some research and think I've done it correct but whenever the view controller launches, I get an error Illegal NSComboBox data source. I thought it may be an issue with the ComboBox (It was copied from another one in the View Controller) so I tried creating one from scratch but I am getting the same thing. I can populate the ComboBox using the addItem no problem. The Combobox does have Use Data Source selected in the Storyboard. Here is my code;

enum Server_Locations: String, CaseIterable {
  case us = "United States"
  case canada = "Canada"
  case other = "Other"
}

class PreferenceController: BaseVC, NSComboBoxDelegate, NSComboBoxDataSource {
@IBOutlet weak var countryComboBox: NSComboBox!

override func viewDidLoad() {
    super.viewDidLoad()

    countryComboBox.dataSource = self
    countryComboBox.delegate = self
    numberOfItemsInComboBoxCell(aComboBox: countryComboBox)
    comboBoxCell(aComboBox: countryComboBox, objectValueForItemAtIndex: 0)
}

func numberOfItemsInComboBoxCell(aComboBox: NSComboBox) -> Int {
    return Server_Locations.allCases.count
  }

func comboBoxCell(aComboBox: NSComboBox, objectValueForItemAtIndex index: Int) -> AnyObject {
    return Server_Locations.allCases[index].rawValue as AnyObject
  }

It seems pretty straightforward but I'm obviously doing something wrong? I think the issue is in the calls to numberOfItemsInComboBoxCell and comboBoxCell I've checked some examples online and they have referencing outlets to the delegate and the dataSource but I am defining them in the viewDidLoad(). I'm using Swift 5 in Storyboard mode with XCode 14.2

Replies

I knew I should have held off a few more minutes. I was able to get this working. My issue was that my function calls for numberOfItemsInComboCell and comboBoxCell were wrong. I fixed it by changing those two calls to;

   func numberOfItems(in comboBox: NSComboBox) -> Int {
   return Server_Locations.allCases.count
  }

and

   func comboBox(_ comboBox: NSComboBox, objectValueForItemAt index: Int) -> Any? {
    return String(KeyboardHotKeys.allCases[index].rawValue) as AnyObject
  }

so

    numberOfItems(in: countryComboBox)
    comboBox(countryComboBox, objectValueForItemAt: 0)

It is now complaining that I am not using the result of the call. Should I bother assigning the result to an empty value (ie: _ =) or is there something else I should be doing with it? The data is populating the NSComboBox as expected.

If you set Use Data Source selected in the Storyboard, why not set delegate and dataSource there as well ?

What is the use of numberOfItemsInComboBoxCell ? You call it but do nothing with the result.

You should instead implement the dataSource functions:

func numberOfItems(in: NSComboBox) -> Int {
   Server_Locations.allCases.count
}

And also

func comboBox(NSComboBox, objectValueForItemAt: Int) -> Any? {
    Server_Locations.allCases[index].rawValue as Any
}
  • @Claude31 So I didn't need the call to the numberOfItems and comboBox as they populate from the "dataSource" in the comboBox function on their own. I added three more NSComboBoxes (They all load value from same source) and they all populated without doing anything other than setting the dataSource and delegate to self for all in the ViewDidLoad(). Is this an OK way of populating the NSComboBoxes? What would I do if I needed to populate different comboboxes with different values?

Add a Comment