macOS - get the AUv3 / AU V2 icon before scanning - solution

Hi folks,

I had an annoying problem, and thought I’d share the solution.

Some time after app start, but before any attempt to re-scan plug-ins: I was trying to pull-out the icons for (previously scanned) Audio Units on macOS.

  NSArray<AVAudioUnitComponent*>* audioComponents = [[AVAudioUnitComponentManager sharedAudioUnitComponentManager] componentsPassingTest:^BOOL(AVAudioUnitComponent * _Nonnull comp, BOOL * _Nonnull stop) {
   ... make sure we match properly, then:
   ... return comp.icon;

The problem was this: the icon wasn’t the correct icon until I’ve actually done a plug-in scan.

Which was puzzling!

NB: on iOS the above approach always works fine.

I tried various approaches, and none of them fixed this issue, e.g.:

  nsImage = audioUnitComponent.icon;

  nsImage = AudioComponentGetIcon(audioUnitComponent.audioComponent);

  auto imageURL = audioUnitComponent.iconURL;
  nsImage = [[NSImage alloc] initWithData:[NSData dataWithContentsOfURL:imageURL]];

  if (@available(macOS 11.0, *)) {
    nsImage = AudioComponentCopyIcon(audioUnitComponent.audioComponent);
  }

The only solution I found was to do this at least once for the Audio Unit in question - the icon was then valid.

  // Instantiate at least once using AVFoundation's AVAudioUnit class method, otherwise the icon won't be available.
  [AVAudioUnit instantiateWithComponentDescription:audioUnitComponent.audioComponentDescription options:kAudioComponentInstantiation_LoadInProcess completionHandler:^(__kindof AVAudioUnit * _Nullable audioUnit, NSError * _Nullable error) {
     // The icon should now be available.
   }];

I hope that helps somebody else out!

Pete

1 Like