The way to do this is to set-up an object as a menu delegate (see NSMenuDelegate
). I set the menu item's tag to a unique value and then find that menu item during startup. I use the App Delegate as the menu delegate and then build the menu by implementing the following delegate methods:
- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu;
- (BOOL)menu:(NSMenu *)menu
updateItem:(NSMenuItem *)item
atIndex:(NSInteger)index
shouldCancel:(BOOL)shouldCancel;
You have the added complication of arbitrarily complex dictionary structure, so you need to create a custom class to store each menu item (the menu text and the selector, as a string, along with anything else you might need). Then store these items and any sub-dictionaries within the main dictionary.
When you come to enumerate the dictionary (in the menu:updateItem:atIndex:shouldCancel:
delegate method) you will need test the type of the object (custom object or dictionary) using isKindOfClass
and in order to deal with the arbitrary nesting, you probably want to use a private, recursive, method that deals with a single dictionary.
Good luck; it's not simple but certainly achievable.