From 251ec6daa8112cf1f56e2ae55cd92148a89fb07c Mon Sep 17 00:00:00 2001 From: ed Date: Wed, 3 Apr 2019 16:59:51 +0100 Subject: [PATCH] iOS: Made it clear that the "Audio Background Capability" setting must be enabled for MidiInput/Output::createNewDevice() to succeed --- .../ProjectSaving/jucer_ProjectExport_Xcode.h | 3 +- .../midi_io/juce_MidiDevices.h | 6 ++++ .../native/juce_mac_CoreMidi.cpp | 28 +++++++++++++++++-- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h index 868686a617..04a2edfee5 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h @@ -334,7 +334,8 @@ public: if (iOS) { props.add (new ChoicePropertyComponent (iosBackgroundAudioValue, "Audio Background Capability"), - "Enable this to grant your app the capability to access audio when in background mode."); + "Enable this to grant your app the capability to access audio when in background mode. " + "This permission is required if your app creates a MIDI input or output device."); props.add (new ChoicePropertyComponent (iosBackgroundBleValue, "Bluetooth MIDI Background Capability"), "Enable this to grant your app the capability to connect to Bluetooth LE devices when in background mode."); diff --git a/modules/juce_audio_devices/midi_io/juce_MidiDevices.h b/modules/juce_audio_devices/midi_io/juce_MidiDevices.h index 809f8a1279..a0675cc3d9 100644 --- a/modules/juce_audio_devices/midi_io/juce_MidiDevices.h +++ b/modules/juce_audio_devices/midi_io/juce_MidiDevices.h @@ -112,6 +112,9 @@ public: This will attempt to create a new midi input device with the specified name for other apps to connect to. + NB - if you are calling this method on iOS you must have enabled the "Audio Background Capability" + setting in the iOS exporter otherwise this method will fail. + Returns nullptr if a device can't be created. @param deviceName the name of the device to create @@ -265,6 +268,9 @@ public: This will attempt to create a new midi output device with the specified name that other apps can connect to and use as their midi input. + NB - if you are calling this method on iOS you must have enabled the "Audio Background Capability" + setting in the iOS exporter otherwise this method will fail. + Returns nullptr if a device can't be created. @param deviceName the name of the device to create diff --git a/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp b/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp index b22b475c04..a4156f0359 100644 --- a/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp +++ b/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp @@ -459,7 +459,19 @@ MidiInput* MidiInput::createNewDevice (const String& deviceName, MidiInputCallba MIDIEndpointRef endpoint; ScopedCFString name (deviceName); - if (CHECK_ERROR (MIDIDestinationCreate (client, name.cfString, midiInputProc, mpc.get(), &endpoint))) + auto err = MIDIDestinationCreate (client, name.cfString, midiInputProc, mpc.get(), &endpoint); + + #if JUCE_IOS + if (err == kMIDINotPermitted) + { + // If you've hit this assertion then you probably haven't enabled the "Audio Background Capability" + // setting in the iOS exporter for your app - this is required if you want to create a MIDI device! + jassertfalse; + return nullptr; + } + #endif + + if (CHECK_ERROR (err)) { auto deviceIdentifier = createUniqueIDForMidiPort (deviceName, true); @@ -582,7 +594,19 @@ MidiOutput* MidiOutput::createNewDevice (const String& deviceName) ScopedCFString name (deviceName); - if (CHECK_ERROR (MIDISourceCreate (client, name.cfString, &endpoint))) + auto err = MIDISourceCreate (client, name.cfString, &endpoint); + + #if JUCE_IOS + if (err == kMIDINotPermitted) + { + // If you've hit this assertion then you probably haven't enabled the "Audio Background Capability" + // setting in the iOS exporter for your app - this is required if you want to create a MIDI device! + jassertfalse; + return nullptr; + } + #endif + + if (CHECK_ERROR (err)) { auto deviceIdentifier = createUniqueIDForMidiPort (deviceName, true);