UIDeferredMenuElement With Uncached Provider Not Working on Mac Catalyst. Uncached provider block never called and menu displays as "Loading"

I'm trying to create a dynamic menu on Mac Catalyst. Using a UIBarButtonitem like so to make a "pull down" button:

    UIDeferredMenuElement *deferredmenuElement;
    deferredmenuElement = [UIDeferredMenuElement elementWithUncachedProvider:^(void (^ _Nonnull completion)(NSArray<UIMenuElement *> * _Nonnull))
    {
        UIAction *actionOne = [UIAction actionWithTitle:@"Action One" image:nil identifier:nil handler:^(__kindof UIAction * _Nonnull action) {
            NSLog(@"action one fired.");
        }];
        
        UIAction *actionTwo = [UIAction actionWithTitle:@"Action Two" image:nil identifier:nil handler:^(__kindof UIAction * _Nonnull action) {
            NSLog(@"action two fired.");
        }];
        
        UIAction *actionThree = [UIAction actionWithTitle:@"Action Three" image:nil identifier:nil handler:^(__kindof UIAction * _Nonnull action) {
            NSLog(@"action three fired.");
        }];
        
        completion(@[actionOne,actionTwo,actionThree]);
    }];
    
    UIMenu *wrappedMenu = [UIMenu menuWithChildren:@[deferredmenuElement]];
    
    UIBarButtonItem *uiBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:nil
                                                                        menu:wrappedMenu];
    
    uiBarButtonItem.image = [UIImage systemImageNamed:@"rectangle.and.pencil.and.ellipsis"];
    self.navigationItem.rightBarButtonItems = @[uiBarButtonItem];

The button appears in the toolbar but when I click it to expose the menu I get a menu with on element in it that says "Loading...". The the uncached provider block is never called.

Running Ventura 13.2.1 and Xcode 14.2.

I filed FB12062113

Haven't seen this on Ventura. On Monterey the whole deferred thing didn't work at all but have used it on most every Ventura version without issue. Though I guess I don't have any menus attached to button bar items. I wonder if not implemented there.

Still not fixed in Ventura 13.3. Can you show your code so I can see what's different from mine? I tried using it with a UIButton instead of UIBarButtonItem and then adding it to my NSToolbar with NSUIViewToolbarItem but still not working. The menu just shows a "Loading..." item and the uncached provider block is never called.

Still broken on Ventura 13.5.2.

Also it doesn't work when creating a pull down UIButton. The following button just show "Loading..." and the provider block is never called:

  UIDeferredMenuElement *deferredmenuElement;
    deferredmenuElement = [UIDeferredMenuElement elementWithUncachedProvider:^(void (^ _Nonnull completion)(NSArray<UIMenuElement *> * _Nonnull))
    {
        UIAction *actionOne = [UIAction actionWithTitle:@"Action One" 
                                                  image:nil
                                             identifier:@"fake.action.test"
                                                handler:^(__kindof UIAction * _Nonnull action) {
            NSLog(@"action one fired.");
        }];
        
        
        completion(@[actionOne]);
    }];
    
    UIMenu *someMenu = [UIMenu menuWithChildren:@[deferredmenuElement]];
    UIButton *pullDownButton = [UIButton buttonWithType:UIButtonTypeSystem];
    [pullDownButton setTitle:@"Pull Down Button" forState:UIControlStateNormal];
    [pullDownButton sizeToFit];
    self.button = pullDownButton;
    self.button.menu = someMenu;
    self.button.showsMenuAsPrimaryAction = YES;
    [self.view addSubview:pullDownButton];
    //Position the button...

On Mac Catalyst I did get the UIDeferredMenuElement elementWithUncachedProvider: block to be called only when creating a menu for a UIContextMenuConfiguration directly but if you're actually loading data async to build the menu you can't use dispatch_async_get_main_queue to call the completion block on the main thread.

 UIDeferredMenuElement *deferredMenuElement = [UIDeferredMenuElement elementWithUncachedProvider:^(void (^ _Nonnull completion)(NSArray<UIMenuElement *> * _Nonnull)) {
     //Load whatever async. 
       dispatch_queue_t queue = dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0);
        dispatch_async(queue, ^{

              //You can't do this. The menu will never update because of the run loop mode.
              dispatch_async(dispatch_get_main_queue(), ^{ 
                      //Build UIMenu with data loaded and call the completion block on the main queue.
                      UIMenu *menu = //...make it
                      completion(@[menu])
                   });
    
               //Instead you have to pass the block to a method like this, then invoke the block.
               [self performSelectorOnMainThread:@selector(builtMenuBlock:)
                                   withObject:completion
                                waitUntilDone:NO
                                        modes:@[NSRunLoopCommonModes]];
}];


Still broken on macOS Sonoma.

Still broken in 14.4.1. Quality software by Apple. Top notch.

I ran into this issue recently and found a workaround to this. Don't attach the menu to the bar button item. Instead use a UIButton as the custom view (sorry about the bastardized ObjC code):

let optionsButton = [UIButton buttonWithType:UIButtonTypeCustom];
[optionsButton setImage:optionsImage forState:UIControlStateNormal];
optionsButton.showsMenuAsPrimaryAction = YES;
optionsButton.menu = menu;
optionsBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:optionsButton];

I want to saw if I changed the button type to .system then I got the same 'Loading...' menu item forever. But when it is custom seems to work. Of course now the bar button item behaves a little differently when the window isn't active so you'll have to write code to tint it to look inactive as needed. But hey the menu works.