Disable Microphone Access on iOS?

I specifically do not want microphone access for my app — it only generates sound but does not need any input. Since some non-tech savy users get scared from seeing the “We need permission for your microphone” popup I tried to turn it off. Disabling it in the Jucer still causes the app to crash:

[access] This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSMicrophoneUsageDescription key with a string value explaining to the user how the app uses this data.

Is there a way to completely disable any attempt on JUCE’s part to get the microphone with an audio app?

Nevermind. This fixed it:

audioDeviceManager.initialise(0, 2, nullptr, true);

I just needed to ask for zero input channels.

1 Like

was just about to ask that :wink:
Glad it works…

1 Like

Gotta love stack traces!

1 Like

You can also set the input channels to 0 in the function call setAudioChannels(inputs, outputs);.

What if that will be Standalone Plugin (iOS) ? Standard app has audioDeviceManager, but not in “Standalone Plugin”.

hpp

#pragma once

#include <JuceHeader.h>

//==============================================================================
/**
*/
class XXXXPluginAudioProcessor  : public juce::AudioProcessor
{
public:
    //==============================================================================
    XXXXPluginAudioProcessor();
    ~XXXXPluginAudioProcessor() override;

    //==============================================================================
    void prepareToPlay (double sampleRate, int samplesPerBlock) override;
    void releaseResources() override;

   #ifndef JucePlugin_PreferredChannelConfigurations
    bool isBusesLayoutSupported (const BusesLayout& layouts) const override;
   #endif

    
    bool supportsDoublePrecisionProcessing() const override;
    
    template<typename T>
    void renderAudio(juce::AudioBuffer<T>& buffer, juce::MidiBuffer& midiMessages);
    
    void processBlock (juce::AudioBuffer<float>&, juce::MidiBuffer&) override;
    void processBlock (juce::AudioBuffer<double>&, juce::MidiBuffer&) override;
    
    //==============================================================================
    juce::AudioProcessorEditor* createEditor() override;
    bool hasEditor() const override;

    //==============================================================================
    const juce::String getName() const override;

    bool acceptsMidi() const override;
    bool producesMidi() const override;
    bool isMidiEffect() const override;
    double getTailLengthSeconds() const override;

    //==============================================================================
    int getNumPrograms() override;
    int getCurrentProgram() override;
    void setCurrentProgram (int index) override;
    const juce::String getProgramName (int index) override;
    void changeProgramName (int index, const juce::String& newName) override;

    //==============================================================================
    void getStateInformation (juce::MemoryBlock& destData) override;
    void setStateInformation (const void* data, int sizeInBytes) override;
    
private:
    //==============================================================================
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (XXXXPluginAudioProcessor)
};

cpp

XXXXPluginAudioProcessor::XXXXPluginAudioProcessor()
#ifndef JucePlugin_PreferredChannelConfigurations
     : AudioProcessor (BusesProperties()
                     #if ! JucePlugin_IsMidiEffect
                      #if ! JucePlugin_IsSynth
                       .withInput  ("Input",  juce::AudioChannelSet::stereo(), true)
                      #endif
                       .withOutput ("Output", juce::AudioChannelSet::stereo(), true)
                     #endif
                       )
#endif
{
    setProcessingPrecision(ProcessingPrecision::doublePrecision);
}

If your preprocessor defines are set so that the .withInput line is excluded, the standalone wrapper will not try to open the microphone:

audioInputRequired is set when an input bus is added to the default.