Cannot determine shown/hidden status of a v3 Audio Unit on macOS

I have some visualisation-heavy AUv3's, and the goal is not to perform graphics-intensive tasks if the plugin window is not opened inside the host app (such as Logic Pro). On iOS, this is easily accomplished by the viewWillAppear, etc overrides. But on macOS, it seems these overrides are not called every time the user opens / closes the plugin windows in the host application.

I did try some alternate methods, like trying to traverse the view / controller hierarchy, or make use of the window property, to no avail.

What substitute mechanism could I use to determine visibility status of an AUv3 on macOS?

Thanks in advance, Zoltan

Replies

What substitute mechanism could I use to determine visibility status of an AUv3 on macOS?

I did some testing as well, none...

Get the complete feedback created by user NikoloziApps here:

After a few email exchanges with an engineer from Apple Developer Technical Support, Case-ID: 1997379, and experimentation, it has become clear that a subclass of AUViewController when used in a MacCatalyst AUv3 plug-in doesn't receive viewWill/DidAppear/Disappear callbacks. SwiftUI’s onAppear, onDisappear and onChange of scenePhase, also aren't getting called. However, when it's a pure macOS AUv3 then it works as expected. And things work correctly on iOS

Reported via FB12145974, and I've just created FB13410524, please do the same and include both refs.

The issue is also mentioned here on both topics:

I found that I can get occlusionState with the following code on both Catalyst and Mac (built for iPad).

I only tested this on MainStage. The code is not tested on iOS/iPadOS devices.

#import "AudioUnitViewController.h"
#import "UnotoneAudioUnit.h"
#import <UIKit/UIKit.h>

@interface NSObject (DUMMY)

- (NSUInteger)occlusionState;
- (NSArray<UIWindow*>*)uiWindows;

@end

@interface AudioUnitViewController () <AUAudioUnitFactory>

@end

@implementation AudioUnitViewController

- (AUAudioUnit *)createAudioUnitWithComponentDescription:(AudioComponentDescription)desc error:(NSError **)error {
    self.audioUnit = [[UnotoneAudioUnit alloc] initWithComponentDescription:desc error:error];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:@"NSWindowDidChangeOcclusionStateNotification" object:nil];

    return self.audioUnit;
}

- (void)handleNotification:(NSNotification *)note
{
    id uinswindow = note.object;
    if ([uinswindow respondsToSelector:@selector(occlusionState)] &&
        [uinswindow respondsToSelector:@selector(uiWindows)]) {
        UIWindow *window = self.view.window;
        NSArray <UIWindow *> *windows = [uinswindow uiWindows];
        if ([windows containsObject:window]) {
            NSUInteger state = [uinswindow occlusionState];
            NSLog(@"OcclusionState: %ld", state); // bit 1 (1UL<<1) is the visible flag.
        }
    }
}

@end