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