2015-10-05 3 views
9

Я только что открыл CABTMIDILocalPeripheralViewController для iOS, который обрабатывает пользовательские настройки, позволяющие обнаруживать Bluetooth MIDI. Это отлично, но для того, чтобы интегрировать bluetooth в остальную часть моего приложения Сетевое подключение MIDI, было бы хорошо иметь возможность обрабатывать , позволяя прямо из кода моего приложения, а не полагаться на этот непрозрачный VC. Кто-нибудь знает, возможно ли это?Реклама Bluetooth MIDI на iOS вручную, без CABTMIDILocalPeripheralViewController

+0

Вы когда-нибудь выясняли, как использовать эти вещи? Я использую CABTMIDICentralViewController, и я действительно хочу проверить, какое MIDI-устройство подключено пользователем в моем коде (так что я могу автоматически подключиться к правильному MIDI-устройству). Есть ли способ сделать это, или мы должны указывать некоторые ошибки с Apple? – phreakhead

+0

Я использую Peripheral-версию, но на основе этого я бы предположил, что после ее подключения он становится MIDIEndpointRef, поэтому вы можете запросить его с помощью CoreMIDI api. Он должен иметь такое имя, как «iPhone Bluetooth Hari Karam». Вы вообще не можете настроить внутренние компоненты VC. И нет другого 'CABTMIDI ...' api, насколько я могу видеть –

+0

Хорошо. Я собрал ужасное решение для взлома, которое я опубликую ниже. – phreakhead

ответ

1

Для управления этой функциональностью нет открытого API. При исследовании с помощью приборов появляется, что переключатель вызывает экземпляр CBPeripheralManager. Я полагаю, он устанавливает устройство в качестве периферии Bluetooth и вручную передает данные в и из созданного MIDIEndpointRef.

Другими словами, нет решения с одним слоем. Если я иду по этому пути дальше, я выложу код, если кто-то не хочет, чтобы идти ...

UPDATE

В магия код ...

- (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]; 
} 

Это те идентификаторы, которые определяют периферию MIDI. Более подробная информация:

Apple не используется, чтобы иметь документ на

... который больше не будет. Мне бы хотелось найти старую копию, так как оказалось, что код приемника (эмуляция CABTMIDICentralViewController) еще труднее взломать ...

0

Я думаю, что вы могли бы искать это: CABTMIDICentralViewController больше информации на этой странице: https://developer.apple.com/library/ios/qa/qa1831/_index.html basicaly это позволяет сканировать и подключаться к устройствам через ваше приложение. Я не уверен, что вы только хотите, чтобы вас обнаружили, а также чтобы он был сканированием. Надеюсь, это поможет

+0

Вот где я узнал о 'CABTMIDILocalPeripheralViewController', который определенно будет использоваться в моем случае. В любом случае, эта страница не описывает, как выполнить задачу, не используя эти VC, которые я хочу знать. –

+0

На самом деле это довольно ограничено, возможно, из-за мешающих безопасности. –

+0

Существуют приложения (например, Apollo Bluetooth), которые выполняют это. Я подозреваю, что они делают это вручную без 'CABT ...' VCs –

1

Итак, я собрал довольно хакерское решение для обнаружения того, какое MIDI-устройство пользователь нажимал один раз внутри CABTMIDICentralViewController. Я не уверен, что это хорошая идея - если 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.м:

#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 не упростила для нас ...

Смежные вопросы