DPBleMidiDeviceManager

DPBleMidiDeviceManager

我刚刚发现了iOS的CABTMIDILocalPeripheralViewController
处理用于启用Bluetooth MIDI可发现性的用户设置。这是
很好,但是为了将蓝牙集成到我的应用程序的其余部分中
网络MIDI连接,能够处理
直接从我的应用程序代码启用,而不是依赖于此不透明的VC。
有人知道这是否可能吗?

最佳答案

因此,我拼凑了一个漂亮的解决方案,以发现用户一次在CABTMIDICentralViewController内部单击了哪个MIDI设备。我不确定这是否是个好主意-如果Apple更改了 Controller 的内部结构,将无法再使用。另外,我不确定有关App Store准则是否“合法”。有人知道更多信息吗?

DPBleMidiDeviceManager.h:

#import <CoreAudioKit/CoreAudioKit.h>

@protocol MidiDeviceConnectedDelegate <NSObject>

-(void) onMidiDeviceConnected: (NSString*) deviceName;

@end


@interface DPBleMidiDeviceManager : CABTMIDICentralViewController

@property (weak, nonatomic) id<MidiDeviceConnectedDelegate> midiDeviceDelegate;

@end

DPBleMidiDeviceManager.m:
#import "DPBleMidiDeviceManager.h"

@implementation DPBleMidiDeviceManager


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"midi device selected %@", indexPath);

    [super tableView:tableView didSelectRowAtIndexPath:indexPath];

    // TODO: this is very bad. apple may change their internal API and this will break.
    UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
    if ([cell respondsToSelector:@selector(deviceNameLabel)]) {
        UILabel* deviceLabel = [cell performSelector:@selector(deviceNameLabel)];

        NSLog(@"midi device named %@", deviceLabel.text);

        // must wait a couple seconds for it to actually connect.
        [self performSelector:@selector(sendMidiDeviceConnected:) withObject:deviceLabel.text afterDelay: 3];
    }
}


- (void) sendMidiDeviceConnected: (NSString*) deviceName
{
    [self.midiDeviceDelegate onMidiDeviceConnected:deviceName];
}
@end

然后,在父 View Controller 中,您可以从委托(delegate)中获取结果,并寻找与该名称匹配的新MIDI设备:
...
    DPBleMidiDeviceManager *controller = [DPBleMidiDeviceManager new];
    controller.midiDeviceDelegate = self;
    // now present the VC as usual
...


-(void) onMidiDeviceConnected: (NSString*) deviceName
{
    [self connectMidiDevice: deviceName];
}


/**
 Connects to a MIDI source with the given name,
 and interprets all notes from that source as notes;

 */
- (void) connectMidiDevice: (NSString*) deviceName
{
    NSLog(@"Connecting to MIDI device: %@", deviceName);

    PGMidi* midi = [[PGMidi alloc] init];

    if (midi != NULL) {
        NSArray* sources = midi.sources;
        for (PGMidiSource* src in sources) {
            NSLog(@"Found midi source: %@", src.name);

            if ([src.name containsString: deviceName]) {

                NSLog(@"Connecting to midi source: %@", src.name);
                [src addDelegate:self];
            }
        }
    }

}

我能想到的唯一其他选择是在显示 Controller 之前先扫描MIDI设备,保存设备列表,然后打开 Controller 。当它关闭时,再次扫描MIDI设备,然后将新列表与旧列表进行比较。出现的任何新MIDI设备都是用户选择的设备。不知道为什么苹果没有让我们更容易...

10-06 03:24