iOS 与外设通信

蓝牙通讯

PS: _notifyCharacteristicID,_writeCharacteristicID,_externalCharacteristicID 都是跟硬件约定好的对应权限的Characteristic特征的uuid

基本概念

  • Peripheral、Central:中心和外设,发起连接的是 Central,被连接的设备为 Peripheral;外设设备会不停地向外广播以寻求连接。 在Mimo里,app的角色是 Central,而相机是 Peripheral

  • Service: 每个service 有唯一的uuid,多个外设可以共用一个service,也就是 扫描指定的uuid的service时,会返回所有使用了该service的 外设(Peripheral) 每个service会有一个或多个 Characteristic(特征),

  • Characteristic:特征,也是设备之间的数据传输通道,每个特征也有唯一的标识符(uuid)。分为 write,notify, Write类型用以 往外设上发送数据。

工作流程(以Central端为例)

  1. 开始扫描使用指定 uuid service的Peripheral 外设
    //创建 CBCentralManager
    _centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:_bleWorkQueue options:options];
//扫描指定的多个uuid的service
    [_centralManager scanForPeripheralsWithServices:_scanServices options:options];
  1. 扫描到Peripheral 信息后,开始连接该外设
- (void)centralManager:(CBCentralManager *)central
 didDiscoverPeripheral:(CBPeripheral *)peripheral
     advertisementData:(NSDictionary<NSString *,
                        id> *)advertisementData
                  RSSI:(NSNumber *)RSSI
{
//发现外设后,尝试连接
[[DJIBLECentralManager defautManager] connectPeripheral:aPeripheral]
}
  1. 连接到外设后,在该外设上检索 指定的service,并监听相关回调
- (void)centralManager:(CBCentralManager *)central
  didConnectPeripheral:(CBPeripheral *)peripheral
{
    [peripheral setDelegate:self];
    [peripheral discoverServices:@[_serviceUUID]];
}
  1. 检索到service以后,开始在该service上检索 Characteristic 特征。
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{

    for (CBService *aService in peripheral.services) {
        if ([aService.UUID isEqual:_serviceUUID]) {
            NSMutableArray *searchUUIDs = [NSMutableArray array];
            if (_notifyCharacteristicID) {
                [searchUUIDs addObject:[CBUUID UUIDWithString:_notifyCharacteristicID]];
            }
            if (_writeCharacteristicID) {
                [searchUUIDs addObject:[CBUUID UUIDWithString:_writeCharacteristicID]];
            }
            if (_externalCharacteristicID) {
                [searchUUIDs addObject:[CBUUID UUIDWithString:_externalCharacteristicID]];
            }
            [peripheral discoverCharacteristics:searchUUIDs forService:aService];
        }
    }
}
  1. 检索到Characteristic 特征以后,就可以用对应类型的特征来做相关事情了,比如用write类型特征往外设上写入数据
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
for (CBCharacteristic *aCharacteristic in service.characteristics) {
        if ([aCharacteristic.UUID isEqual:[CBUUID UUIDWithString:_writeCharacteristicID]]) {
            self.writeCharacteristic = aCharacteristic;
        }
}
//往write类型的特征通道上写入数据
 [_peripheral writeValue:sendData forCharacteristic:_writeCharacteristic type:CBCharacteristicWriteWithoutResponse];
}

或是接收来自某个 特征通道的数据

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error
{
    NSData * updatedValue = characteristic.value;
}

MFI 认证通讯

什么是MFI

苹果 MFi 认证,是苹果公司(Apple Inc.)对其授权配件厂商生产的外置配件的一种标识使用许可,是 Apple 公司 “Made for iOS” 的英文缩写。

为什么要做 MFi 认证

iOS App 跟外设的连接方式有网络、EAP 和 BLE。 只有经过 MFi 认证的外设才能使用 EAP(External Accessory Protocol) 跟 App 进行通信。

因为如果采用 EAP,那么对应的 App 就必须集成苹果的 EA 框架(ExternalAccessory.framework)