目前在使用蓝牙串口模块,而厂家给的库文件使用几小时就会无法收到消息,而且因为只支持ARM架构所以只能真机调式,所以决定花点时间自己重新编写蓝牙底层代码。这只是题外话。
BLE (Bluetooth Low Energy)主要有2个概念:服务(Services)和属性(Characteristics), 一个BLE设备有多个Services, 在每个Service底下又拥有多个Characteristics. 如果你想要和一个蓝牙进行通信, 除了与先与它进行连接外, 还需要判断这个设备是不是你所支持的设备类型. 如果你搜索到了附近有多个BLE设备, 它们有血压检测仪、脉搏计数器等, 要先判断这个BLE设备有没有这个Services, 才能进行通信. 然后再通过Characteristics来进行数据传输.
苹果官方例程 https://developer.apple.com/library/ios/samplecode/BTLE_Transfer/Introduction/Intro.html
@interface BTLECentralViewController () <CBCentralManagerDelegate, CBPeripheralDelegate>
{
@property (strong, nonatomic) CBCentralManager *centralManager;
@property (strong, nonatomic) CBPeripheral *discoveredPeripheral;
}
- (void)initBLE
{
// Start up the CBCentralManager
_centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
[self.centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]]
options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @YES }];
}
// 找到设备委托方法. 注意这里每找到一个设备就会被调用
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
NSLog(@"Discovered %@ at %@", peripheral.name, RSSI);
// Ok, it's in range - have we already seen it?
if (self.discoveredPeripheral != peripheral) {
// Save a local copy of the peripheral, so CoreBluetooth doesn't get rid of it
self.discoveredPeripheral = peripheral;
// And connect
NSLog(@"Connecting to peripheral %@", peripheral);
[self.centralManager connectPeripheral:peripheral options:nil];
}
}
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
NSLog(@"Failed to connect to %@. (%@)", peripheral, [error localizedDescription]);
}
// 已经连接通知
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
NSLog(@"Peripheral Connected");
// Stop scanning
[self.centralManager stopScan];
NSLog(@"Scanning stopped");
// Make sure we get the discovery callbacks
peripheral.delegate = self;
// Search only for services that match our UUID
[peripheral discoverServices:@[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]]];
}
// 找到我们刚刚指定的服务
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
if (error) {
NSLog(@"Error discovering services: %@", [error localizedDescription]);
return;
}
// Discover the characteristic we want...
// Loop through the newly filled peripheral.services array, just in case there's more than one.
for (CBService *service in peripheral.services) {
[peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_UUID]] forService:service];
}
}
// 找到我们刚刚指定的属性
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
// Deal with errors (if any)
if (error) {
NSLog(@"Error discovering characteristics: %@", [error localizedDescription]);
return;
}
// Again, we loop through the array, just in case.
for (CBCharacteristic *characteristic in service.characteristics) {
// And check if it's the right one
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_UUID]]) {
// If it is, subscribe to it
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
}
// Once this is complete, we just need to wait for the data to come in.
}
- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
if (error) {
NSLog(@"Error changing notification state: %@", error.localizedDescription);
}
// Exit if it's not the transfer characteristic
if (![characteristic.UUID isEqual:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_UUID]]) {
return;
}
// Notification has started
if (characteristic.isNotifying) {
NSLog(@"Notification began on %@", characteristic);
}
// Notification has stopped
else {
// so disconnect from the peripheral
NSLog(@"Notification stopped on %@. Disconnecting", characteristic);
[self.centralManager cancelPeripheralConnection:peripheral];
}
}
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
NSLog(@"Peripheral Disconnected");
self.discoveredPeripheral = nil;
// We're disconnected, so start scanning again
[self scan];
}