這篇文章主要包括iOS藍牙開發(fā)的簡介以及如果進行藍牙開發(fā), 具體的藍牙知識不再詳細介紹了.
iOS藍牙開發(fā)的實現基本上都是基于<CoreBlueTooth.framework>這個框架的, 這是目前世界上最流行的框架
可用于第三方藍牙設備交互, 必須要支持藍牙4.0
硬件至少是4s, 系統(tǒng)至少是iOS6
藍牙4.0以低功耗著稱, 一般也叫BLE(BlueTooth Low Energy)
Core Bluetooth的基本常識
- 每個藍牙4.0設備都是通過服務(Service)和特征(Characteristic)來展示自己的
- 一個設備包含一個或多個服務, 每個服務下面又包含若干個特征
- 特征是與人交互的最小單位
- 服務特征都是用UUID來唯一標識的, 通過UUID就能區(qū)別不同的服務和特征
- 設備里面各個服務和特征的功能, 都是由藍牙設備硬件廠商提供, 比如哪些是用來交互, 哪些可以獲取模塊信息等等.
Core Bluetooth的開發(fā)步驟
建立中心設備:
CBCentralManager *manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
掃描外設:
#pragma mark 1
//掃描語句:寫nil表示掃描所有的藍牙外設,如果傳上面的kServiceUUID, 那么只能掃描出這個Service的Peripherals
[self.manager scanForPeripheralsWithServices:nil options:nil];
#pragma mark 2 == 發(fā)現外設
/**
成功掃描到了藍牙會自動進入:didDiscoverPeripheral這個函數
@param peripheral peripheral.name 掃描到的藍牙的名字
@param RSSI 距離
*/
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI
{
NSString *localName = [[advertisementData objectForKey:@"kCBAdvDataLocalName"] lowercaseString];
NSString *peripheralName = [peripheral.name lowercaseString];
NSLog(@"廣播--:%@ 設備--:%@ 距離--:%@",localName, peripheralName, RSSI);
//要連接藍牙的名
NSString *MyBlueToothName = @"要連接藍牙的名";
self.peripheral = peripheral;
/**
連接設備
*/
if ([localName isEqualToString:MyBlueToothName ]|| [peripheralName isEqualToString:MyBlueToothName]) {
self.peripheral.delegate = self;
[self connect:peripheral];
}
}
#pragma mark 3 == 成功連接Peripheral
/**
連接設備成功后會調用該方法
*/
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
//傳nil會尋找所有服務
NSLog(@"連接成功");
[peripheral discoverServices:nil];
//連接成功, 停止掃描
[self.manager stopScan];
}
/**
連接失敗會調用該方法
*/
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
NSLog(@"連接失敗---%@", error);
}
連接外設:
//連接指定的設備
- (BOOL)connect:(CBPeripheral *)peripheral
{
NSLog(@"正在連接指定設備");
[self.manager connectPeripheral:peripheral options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]];
return (YES);
}
掃描外設中的服務和特征:
#pragma mark 4 == 發(fā)現服務
/**
找到server后會調用該方法
*/
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
if (peripheral != self.peripheral) {
NSLog(@"Wrong peripheral");
return;
}
if (error) {
NSLog(@"Error---%@", error);
return;
}
if (!error) {
for (CBService *service in peripheral.services) {
NSLog(@"serviceUUID:%@", service.UUID.UUIDString);
//發(fā)現特定服務的特征值
if ([service.UUID.UUIDString isEqualToString:kServiceUUID]) {
[service.peripheral discoverCharacteristics:nil forService:service];
return;
}
}
}
}
#pragma mark 5 == 發(fā)現Characteristics
/**
找到Characteristics后會調用該方法
*/
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
if (peripheral != self.peripheral) {
NSLog(@"Wrong peripheral");
return;
}
if (error) {
NSLog(@"Error---%@", error);
return;
}
// 遍歷服務中所有的特征值
for (CBCharacteristic *characteristic in [service characteristics])
{
// 找到我們需要的特征
if ([characteristic.UUID isEqual:kCharacteristicUUID])
{
NSLog(@"serviceUUID--:%@", service.UUID);
NSLog(@"CharacteristicsUUID--:%@", characteristic.UUID);
self.characteristic = characteristic;
/**
找到特征以后進行的操作
*/
// //我們可以使用readValueForCharacteristic:來讀取數據,如果數據是不斷更新的,則可以使用setNotifyValue:forCharacteristic:來實現只要有新數據,就獲取
// [self.peripheral readValueForCharacteristic:self.characteristic];
[self.peripheral setNotifyValue:YES forCharacteristic:self.characteristic];
break;
}
}
}
利用特征與外設做數據交互
#pragma mark 6 == 獲取設備返回的數據
/**
讀取到數據就會調用該方法
*/
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
NSData *data = characteristic.value;
//
NSLog(@"data = %@", data);
}
#pragma mark Other == 數據交互
/**
向設備寫數據
@param data 要寫入的數據
*/
- (void)writeValue:(NSData *)data
{
[self.peripheral writeValue:data forCharacteristic:self.characteristic type:CBCharacteristicWriteWithResponse];
}
/**
當writeValue: forCharacteristic: type:方法被調用的時候就會調用該方法
*/
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
//查詢數據是否寫入
NSLog(@"%@", characteristic.value);
}
斷開連接
#pragma mark == 外設斷開連接
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
NSLog(@"連接中斷---%@", error);
}
這只是藍牙開發(fā)的一個流程, 真正用到項目中的話還是需要自己不斷學習和了解才能運用到藍牙項目當中. 不過當你真正了解了藍牙的相關知識就會發(fā)現, 實際上比想象的要更簡單.
附上demo鏈接, 如有不懂, 請下載demo另行查看:
https://github.com/LeoTnT/BlueToothDemo