Finder Sync: Sender passed to action is different instance of NSMenuItem

469 views Asked by At

I have implemented a Finder Sync extension according to the provided sample given from Apple.

After clicking on the newly created contextual menu item the according action sampleAction is executed. Unfortunately the sender passed to the method does not match the instance created in menuForMenuKind.

The code

- (NSMenu *)menuForMenuKind:(FIMenuKind)whichMenu
{
    NSMenuItem* menuItem = [[NSMenuItem alloc] initWithTitle:@"testTitle" action:@selector(sampleAction:) keyEquivalent:@""];
    menuItem.tag = 1;

    // print menu attributes
    NSLog(@"------------------original menu-----------------");
    NSLog(@"menu address: %p", menuItem);
    NSLog(@"menu tag: %ld", menuItem.tag);
    NSLog(@"menu title: '%@'", menuItem.title);

    NSMenu *menu = [[NSMenu alloc] initWithTitle:@""];
    [menu addItem:menuItem];

    return menu;
}

- (IBAction)sampleAction:(id)sender
{
    if( [sender isKindOfClass:[NSMenuItem class]])
    {
        NSMenuItem* menuItem = sender;

        NSLog(@"------------------menu passed to action-----------------");
        NSLog(@"menu address: %p", menuItem);
        NSLog(@"menu tag: %ld", menuItem.tag);
        NSLog(@"menu title: '%@'", menuItem.title);
    }
}

results in the following output after I clicked on the element in the context menu

2014-12-07 19:55:36.923 FinderSync Extension[1265:62630] ------------------original menu----------------
2014-12-07 19:55:36.923 FinderSync Extension[1265:62630] menu address: 0x6080000abbe0
2014-12-07 19:55:36.924 FinderSync Extension[1265:62630] menu tag: 1
2014-12-07 19:55:36.924 FinderSync Extension[1265:62630] menu title: 'testTitle'
2014-12-07 19:55:40.328 FinderSync Extension[1265:62630] ------------------menu passed to action----------------
2014-12-07 19:55:40.328 FinderSync Extension[1265:62630] menu address: 0x6080000aba00
2014-12-07 19:55:40.328 FinderSync Extension[1265:62630] menu tag: 0
2014-12-07 19:55:40.328 FinderSync Extension[1265:62630] menu title: ''

.

Is there any chance to link the sender to the menu item, which was clicked on?

2

There are 2 answers

0
dejuknow On

For reference, this is apparently intended behavior. I filed a bug report with Apple, and this was their response:

This issue behaves as intended based on the following:

Finder Sync does not keep around the specific NSMenuItem* instances, and very few properties are respected (only title, action, image, and enabled). In a future release, the -tag property is likely to be supported, but not -representedObject. — If you require a dynamic set of actions, it should be possible to use functions such as sel_registerName and method_setImplementation (in ) to create methods at runtime.

0
pkamb On

The FIFinderSyncController / FIFinderSyncProtocol docs offer the best documentation for these menus and methods that I can find.

menu(for menu: FIMenuKind)

Specific menu item properties are used: title, action, image, and enabled.

Starting in 10.11: tag, state, and indentationLevel also work, and submenus are allowed.

The tag property that was not persisted when you asked this question is now persisted in macOS 10.11+.

The representedObject property is not persisted by the time we get the callback, which would be extremely useful. The NSMenuItem object is different by that point as well.

It's not ideal, but the now-persisted (and invisible to the user) tag field should be enough to pass information from menu creation and action callback.