生活随笔
收集整理的這篇文章主要介紹了
iOS 蓝牙开发 swift (一)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
iOS 藍牙開發
- 1.藍牙簡介
- 2. 藍牙連接
- 2.1 CoreBluetooth框架
- 2.2 外設、服務、特征間的關系
- 2.3 藍牙連接過程
- 2.4 藍牙中心模式,外設模式
- 2.5 藍牙設備狀態
- 2.6 藍牙連接代碼實現
1.藍牙簡介
-
藍牙模式簡介
藍牙開發分為兩種模式,中心模式(central),和外設模式(peripheral)。一般來講,我們需要在軟件內連接硬件,通過連接硬件給硬件發送指令以完成一些動作的藍牙開發都是基于中心模式(central)模式的開發,也就是說我們開發的app是中心,我們要連接的硬件是外設。如果需要其他設備連接手機藍牙,并對手機進行一些操作,那就是基于外設模式(peripheral)的開發。 本次我們主要介紹的就是中心模式的藍牙開發
-
設備簡介
中心設備(CBCentralManager):iOS系統的手機等設備
外圍設備(CBPeripheral):手環等第三方設備
-
藍牙數據傳輸簡介
將外圍設備(車輛)的數據傳送給中心設備(手機)時, 數據是經過兩層包裝的
第一層是 Service(服務) , 可以是一個或多個, 比如車輛數據(服務)
第二層是 Characteristic(特征) , 他提供了更多關于Service(服務)的數據, 例如車輛數據(服務)中包含了兩個數據, 分別是里程數據和續航數據, 這兩個就是車輛數據(服務)的具體數據(特征)
-
具體操作簡介
讀(read) , 寫(write) , 訂閱(notify)
我們的目的是讀取設備中的數據(read) , 或者給設備寫入一定的數據(write)。有時候我們還想設備的數據變化的時候不需要我們手動去讀取這個值,需要設備自動通知我們它的值變化了,值是多少。把值告訴app,這個時候就需要訂閱這個特征了(notify)
-
其他相關概念
目前都使用的是低功耗藍牙4.0,藍牙外設必需為4.0及以上(2.0需要MFI認證),否則無法開發,藍牙4.0設施由于低耗電,所以也叫做BLE。CoreBluetooth框架的核心其實是兩個東西,peripheral和central, 能了解成外設和中心,就是你的蘋果手機就是中心,外部藍牙稱為外設。服務和特征(service characteristic):簡而言之,外部藍牙中它有若干個服務service(服務你能了解為藍牙所擁有的可以力),而每個服務service下擁有若干個特征characteristic(特征你能了解為解釋這個服務的屬性)。Descriptor(形容)使用來形容characteristic變量的屬性。例如,一個descriptor能規定一個可讀的形容,或者者一個characteristic變量可接受的范圍,或者者一個characteristic變量特定的單位。我們用的藍牙板塊是在淘寶買的, 大概十多元一個, ios大概每次能接受90個字節, 安卓大概每次能接收20個字節, 具體數字可可以會浮動, 應該是與藍牙板塊有關。
2. 藍牙連接
自己實踐的兩個藍牙demo:
OC 編寫的:Bluetooth4_configWifiswifit編寫的:KYLBluetoothDemo_swift
2.1 CoreBluetooth框架
CoreBluetooth框架的核心其實是兩個東西,peripheral和central, 可以理解成外設和中心。對應他們分別有一組相關的API和類
- 這兩組api分別對應不同的業務場景,左側叫做中心模式,就是以你的app作為中心,連接其他的外設的場景,而右側稱為外設模式,使用手機作為外設別其他中心設備操作的場景。
- 服務和特征,特征的屬性(service and characteristic):
每個設備都會有一些服務,每個服務里面都會有一些特征,特征就是具體鍵值對,提供數據的地方。每個特征屬性分為這么幾種:讀,寫,通知這么幾種方式。
typedef
NS_OPTIONS(NSUInteger, CBCharacteristicProperties) {CBCharacteristicPropertyBroadcast = 0x01,CBCharacteristicPropertyRead = 0x02,CBCharacteristicPropertyWriteWithoutResponse = 0x04,CBCharacteristicPropertyWrite = 0x08,CBCharacteristicPropertyNotify = 0x10,CBCharacteristicPropertyIndicate = 0x20,CBCharacteristicPropertyAuthenticatedSignedWrites = 0x40,CBCharacteristicPropertyExtendedProperties = 0x80,CBCharacteristicPropertyNotifyEncryptionRequired NS_ENUM_AVAILABLE(NA, 6_0) = 0x100,CBCharacteristicPropertyIndicateEncryptionRequired NS_ENUM_AVAILABLE(NA, 6_0) = 0x200
};
2.2 外設、服務、特征間的關系
2.3 藍牙連接過程
創建中心設備(CBCentralManager)中心設備開始掃描(scanForPeripherals)掃描到外圍設備之后, 自動調用中心設備的代理方法(didDiscoverPeripheral)如果設備過多, 可以將掃描到的外圍設備添加到數組開始連接, 從數組中過濾出自己想要的設備, 進行連接(connectPeripheral)連接上之后, 自動調用中心設備的代理方法(didConnectPeripheral), 在代理中, 進行查找外圍設備的服務(peripheral.discoverServices)查找到服務之后, 自動調用外圍設備的代理(didDiscoverServices), 可通過UUID,查找具體的服務,查找服務(discoverCharacteristics)查找到特征之后, 自動調用外圍設備的代理(didDiscoverCharacteristics), 通過UUID找到自己想要的特征, 讀取特征(readValueForCharacteristic)讀取到特征之后, 自動調用外設的代理方法(didUpdateValueForCharacteristic),在這里打印或者解析自己想要的特征值.
2.4 藍牙中心模式,外設模式
2.4.1 藍牙中心模式
建立中心角色
掃描外設(discover)
連接外設(connect)
掃描外設中的服務和特征(discover)
4.1 獲取外設的services
4.2 獲取外設的Characteristics,獲取Characteristics的值,獲取Characteristics的 Descriptor和Descriptor的值
與外設做數據交互(explore and interact)
訂閱Characteristic的通知
斷開連接(disconnect)
2.4.2 藍牙外設模式
啟動一個Peripheral管理對象
本地Peripheral設置服務,特性,描述,權限等等
Peripheral發送廣告
設置處理訂閱、取消訂閱、讀characteristic、寫characteristic的委托方法
2.5 藍牙設備狀態
-
藍牙設備狀態
待機狀態(standby):設備沒有傳輸和發送數據,并且沒有連接到任何設
廣播狀態(Advertiser):周期性廣播狀態
掃描狀態(Scanner):主動尋找正在廣播的設備
發起鏈接狀態(Initiator):主動向掃描設備發起連接。
主設備(Master):作為主設備連接到其他設備。
從設備(Slave):作為從設備連接到其他設備。
-
藍牙設備的五種工作狀態
準備(standby)
廣播(advertising)
監聽掃描(Scanning
發起連接(Initiating)
已連接(Connected)
2.6 藍牙連接代碼實現
初始化
self.centralManager
= [[CBCentralManager alloc
] initWithDelegate
:self queue
:nil];
搜索掃描外圍設備
- (void
)centralManagerDidUpdateState
:(CBCentralManager *)central
{switch (central
.state
) {case CBCentralManagerStateUnknown:NSLog(@
">>>CBCentralManagerStateUnknown");break;case CBCentralManagerStateResetting:NSLog(@
">>>CBCentralManagerStateResetting");break;case CBCentralManagerStateUnsupported:NSLog(@
">>>CBCentralManagerStateUnsupported");break;case CBCentralManagerStateUnauthorized:NSLog(@
">>>CBCentralManagerStateUnauthorized");break;case CBCentralManagerStatePoweredOff:NSLog(@
">>>CBCentralManagerStatePoweredOff");break;case CBCentralManagerStatePoweredOn:{NSLog(@
">>>CBCentralManagerStatePoweredOn");[self.centralManager scanForPeripheralsWithServices
:nil options
:nil];}break;default:break;}
}#pragma mark 發現外設
- (void
)centralManager
:(CBCentralManager *)central didDiscoverPeripheral
:(CBPeripheral *)peripheral advertisementData
:(NSDictionary*)advertisementData
RSSI:(NSNumber *)RSSI{NSLog(@
"Find device:%@", [peripheral name
]);if (![_deviceDic objectForKey
:[peripheral name
]]) {NSLog(@
"Find device:%@", [peripheral name
]);if (peripheral
!=nil) {if ([peripheral name
]!=nil) {if ([[peripheral name
] hasPrefix
:@
"根據設備名過濾"]) {[_deviceDic setObject
:peripheral forKey
:[peripheral name
]];
if ([self.delegate respondsToSelector
:@
selector(dataWithBluetoothDic
:)]) {[self.delegate dataWithBluetoothDic
:_deviceDic
];}}}}}
}
連接外圍設備
- (void
)connectDeviceWithPeripheral
:(CBPeripheral *)peripheral
{[self.centralManager connectPeripheral
:peripheral options
:nil];
}#pragma mark 連接外設
--成功
- (void
)centralManager
:(CBCentralManager *)central didConnectPeripheral
:(CBPeripheral *)peripheral
{[central stopScan
];peripheral
.delegate
= self;self.peripheral
= peripheral
;[peripheral discoverServices
:@
[[CBUUID UUIDWithString:@
"你要用的服務UUID"]]];if ([self.delegate respondsToSelector
:@
selector(didConnectBle
)]) {[self.delegate didConnectBle
];}
}#pragma mark 連接外設——失敗
- (void
)centralManager
:(CBCentralManager *)central didFailToConnectPeripheral
:(CBPeripheral *)peripheral error
:(NSError *)error
{NSLog(@
"%@", error
);
}#pragma mark 取消與外設的連接回調
- (void
)centralManager
:(CBCentralManager *)central didDisconnectPeripheral
:(CBPeripheral *)peripheral error
:(NSError *)error
{NSLog(@
"%@", peripheral
);
}
獲得外圍設備的服務
#pragma mark 發現服務回調
- (void
)peripheral
:(CBPeripheral *)peripheral didDiscoverServices
:(NSError *)error
{CBService * __nullable findService
= nil;for (CBService *service
in peripheral
.services
){if ([[service
UUID] isEqual
:[CBUUID UUIDWithString:@
"你要用的服務UUID"]]){findService
= service
;}}NSLog(@
"Find Service:%@",findService
);if (findService
)[peripheral discoverCharacteristics
:NULL forService
:findService
];
}#pragma mark 發現特征回調
- (void
)peripheral
:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService
:(CBService *)service error
:(NSError *)error
{for (CBCharacteristic *characteristic
in service
.characteristics
) {if ([characteristic
.UUID isEqual
:[CBUUID UUIDWithString:@
"你要用的特征UUID"]]) {self.characteristic
= characteristic
;
[peripheral setNotifyValue
:YES forCharacteristic
:characteristic
];NSData *data
= [@
"硬件工程師給我的指令, 發送給藍牙該指令, 藍牙會給我返回一條數據" dataUsingEncoding
:NSUTF8StringEncoding];[self.peripheral writeValue
:data forCharacteristic
:characteristic type
:CBCharacteristicWriteWithResponse];}[peripheral discoverDescriptorsForCharacteristic
:characteristic
];}
}
從外圍設備讀取數據
#pragma mark
- 獲取值
- (void
)peripheral
:(CBPeripheral *)peripheral didUpdateValueForCharacteristic
:(CBCharacteristic *)characteristic error
:(NSError *)error
{NSData *jsonData
= [characteristic
.value dataUsingEncoding
:NSUTF8StringEncoding];NSDictionary *dataDic
= [NSJSONSerialization JSONObjectWithData:jsonData options
:NSJSONReadingMutableContainers error
:nil];
}#pragma mark
- 中心讀取外設實時數據
- (void
)peripheral
:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic
:(CBCharacteristic *)characteristic error
:(NSError *)error
{if (characteristic
.isNotifying
) {[peripheral readValueForCharacteristic
:characteristic
];} else { NSLog(@
"Notification stopped on %@. Disconnecting", characteristic
);NSLog(@
"%@", characteristic
);[self.centralManager cancelPeripheralConnection
:peripheral
];}
}
給外圍設備發送(寫入)數據
- (void
)writeCheckBleWithBle
{_style
= 1;NSData *data
= [@
"硬件工程師提供給你的指令, 類似于5E16010203...這種很長一串" dataUsingEncoding
:NSUTF8StringEncoding];[self.peripheral writeValue
:data forCharacteristic
:self.characteristic type
:CBCharacteristicWriteWithResponse];
}#pragma mark 數據寫入成功回調
- (void
)peripheral
:(CBPeripheral *)peripheral didWriteValueForCharacteristic
:(CBCharacteristic *)characteristic error
:(NSError *)error
{NSLog(@
"寫入成功");if ([self.delegate respondsToSelector
:@
selector(didWriteSucessWithStyle
:)]) {[self.delegate didWriteSucessWithStyle
:_style
];}
}
停止掃描
#pragma mark 停止掃描外設
- (void
)stopScanPeripheral
{[self.centralManager stopScan
];
}#pragma mark 掃描外設
- (void
)scanDevice
{if (_centralManager
== nil) {self.centralManager
= [[CBCentralManager alloc
] initWithDelegate
:self queue
:nil];[_deviceDic removeAllObjects
];}
}
斷開連接
#pragma mark 斷開連接
- (void
)disConnectPeripheral
{[self.centralManager cancelPeripheralConnection
:self.peripheral
];
}
總結
以上是生活随笔為你收集整理的iOS 蓝牙开发 swift (一)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。