在iOS上手动播放蓝牙MIDI,无需CABTMIDILocalPeripheralViewController

时间:2015-10-05 20:35:32

标签: ios bluetooth bluetooth-lowenergy ios9 coremidi

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

4 个答案:

答案 0 :(得分:1)

没有公共API来管理此功能。在使用Instruments进行调查后,交换机似乎会导致white-space: nowrap;的实例化。我认为它将设备设置为蓝牙外围设备,并手动将数据传入和传出已创建的CBPeripheralManager

换句话说,没有单线解决方案。如果我进一步沿着这条路走下去,我会发布代码,除非别人想要去...

<强>更新

magic 代码......

MIDIEndpointRef

这是定义MIDI外设的ID。更多信息:

Apple过去常常有

的文档

......不再是。我很想找到一个旧版本,因为事实证明接收器代码(仿真- (instancetype)init { self = [super init]; if (self) { _peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil]; } return self; } //--------------------------------------------------------------------- - (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral { if (peripheral.state != CBPeripheralManagerStatePoweredOn) { return; } info(@"_peripheralManager powered on."); // CBMutableCharacteristic *tx = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:RBL_TX_UUID] properties:CBCharacteristicPropertyWriteWithoutResponse value:nil permissions:CBAttributePermissionsWriteable]; // rx = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:@"7772E5DB-3868-4112-A1A9-F2669D106BF3"] properties:CBCharacteristicPropertyRead|CBCharacteristicPropertyWriteWithoutResponse|CBCharacteristicPropertyNotify value:nil permissions:CBAttributePermissionsReadable|CBAttributePermissionsWriteable]; CBMutableService *s = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:@"03B80E5A-EDE8-4B33-A751-6CE34EC4C700"] primary:YES]; s.characteristics = @[rx]; [_peripheralManager addService:s]; NSDictionary *advertisingData = @{CBAdvertisementDataLocalNameKey : BLE_NAME, CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:@"03B80E5A-EDE8-4B33-A751-6CE34EC4C700"]]}; [_peripheralManager startAdvertising:advertisingData]; } )更难破解...

答案 1 :(得分:1)

所以我拼凑了一个非常讨厌的解决方案,用于发现用户在CABTMIDICentralViewController中点击了哪个MIDI设备。我不确定这是不是一个好主意 - 如果Apple改变了控制器的内部,它将不再起作用。此外,我不确定它是否与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

然后,在父视图控制器中,您可以从委托中获取结果并查找与该名称匹配的新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];
            }
        }
    }

}

我能想到的唯一另一种选择是在显示控制器之前扫描MIDI设备,保存设备列表,然后打开控制器。关闭时,再次扫描MIDI设备,并将旧列表与旧列表区分开来。显示的任何新MIDI设备都是用户选择的设备。不知道为什么Apple没有让我们这么容易......

答案 2 :(得分:1)

这是Swift 5版本。这很好。

Click

答案 3 :(得分:0)

我认为你可能正在寻找这个:CABTMIDICentralViewController 此页面上的更多信息:https://developer.apple.com/library/ios/qa/qa1831/_index.html  基本可以帮助您通过应用扫描并连接到设备。我不确定你是想要被发现还是想成为扫描者。 我希望这有帮助