围绕 Core Bluetooth 框架的基于块的包装器。这仅是 v1.0 版本,仅包括中央管理器部分,外围管理器部分仍在开发中。
Core Bluetooth
SCPCoreBluetoothManager 通过 CocoaPods 提供。要安装它,只需将以下行添加到 Podfile 中
pod 'SCPCoreBluetoothManager'
注意示例使用 coc napods 包含了 SVProgressHUD 依赖项,因此您需要在终端中运行 pod install
命令。1. 将此存储库作为子模块添加或将其作为 .zip 下载。2. 在示例项目中您将看到一个名为 SCPCoreBluetoothManager 的文件夹。此文件夹包含所有必需的文件。3. 将此文件夹包含到您的项目中。4. 当您希望使用框架时,使用 #import "SCPCoreBluetoothManger.h"
将框架导入到实现中。
了解两个蓝牙低功耗 (BLE) 设备之间的传输。其中一款设备应作为 中央管理器,另一款作为 外围设备。
中央管理器处理监听外围设备并从它们读取数据,外围管理器处理服务的广播、特性和它们的值。
检索数据的三步是:
值得注意的是,外围设备可以有一个或多个服务。一个服务可以有一个或多个特性。
该框架分为两部分,SCPCoreBluetoothCentralManager 和 SCPCoreBluetoothPeripheralManager。SCPCoreBluetoothPeripheralManager 仍在开发中。
请注意所有调用都在后台线程中发生,任何UI更新都必须在主线程上执行。为了在代码块中完成此操作,请简单地将您的UI代码包围在以下代码中。
dispatch_sync(dispatch_get_main_queue(), ^{
//If you need to do any UI updates it must be performed on the main thread
//Add UI code here such as reloading table view data.
});
第一部分专注于读取外围设备、服务和特征。
首先需要启动中央管理器。将SCPCoreBluetoothCentralManager的属性添加到您的类中,并初始化一个新的实例。self.centralManger = [[SCPCoreBluetoothCentralManager alloc] init];
现在需要启动中央管理器。调用实例方法- (void)startUpSuccess:(StartUpSuccess)success failure:(StartUpFailure)failure;
。这需要两个块。如果中央管理器成功启动,将调用第一个块;如果存在问题,将调用第二个块。失败块将返回一个CBCentralManagerState,可以用来确定问题。
//Start up the central manager
[_centralManger startUpSuccess:^{
NSLog(@"Core bluetooth manager successfully started.");
//Once the central manager is successfully started, start scanning for peripherals
[weakSelf scanForPeripherals];
} failure:^(CBCentralManagerState CBCentralManagerState) {
//Handel the error.
NSString *message;
switch (CBCentralManagerState) {
case CBCentralManagerStateUnknown:
{
message = @"Unknown state";
break;
}
case CBCentralManagerStateResetting:
{
message = @"Central manager is resetting";
break;
}
case CBCentralManagerStateUnsupported:
{
message = @"Your device is not supported";
NSLog(@"Please note it will not work on a simulator");
break;
}
case CBCentralManagerStateUnauthorized:
{
message = @"Unauthorised";
break;
}
case CBCentralManagerStatePoweredOff:
{
message = @"Bluetooth is switched off";
break;
}
default:
{
//Empty default to remove switch warning
break;
}
}
dispatch_sync(dispatch_get_main_queue(), ^{
//Add UI code here such as reloading table view data.
});
NSLog(@"Error %d", message);
}];
一旦中央管理器成功启动,现在可以使用此方法查找外围设备:- (void)scanForPeripheralsWithServices:(NSArray *)services allowDuplicates:(BOOL)allowDuplicates didDiscoverPeripheral:(DidDiscoverPeripheral)didDiscoverPeripheral;
。如果给定一个'CBUUID'数组,它将只返回广播包含'CBUUID'之一的服务的外围设备。如果传递了'nil',则将搜索所有这些。允许重复的BOOL指定是否应该进行不重复过滤的扫描。最后,在新外围设备找到时将被调用的块。这将返回外围设备、其广告数据和其RSSI。RSSI是外围设备的当前接收信号强度指示器(RSSI),单位为分贝。
//Check that the central manager is ready to scan
if([_centralManger isReady])
{
//Tell the central manager to start scanning
[_centralManger scanForPeripheralsWithServices:nil //If an array of CBUUIDs is given it will only look for the peripherals with that CBUUID
allowDuplicates:NO
didDiscoverPeripheral:^(CBPeripheral *peripheral, NSDictionary *advertisementData, NSNumber *RSSI) {
//A peripheral has been found
NSLog(@"Discovered Peripheral '%@' with RSSI of %@", [peripheral name], RSSI);
}];
NSLog(@"Scanning started");
}
else
{
NSLog(@"Central manager not ready to scan");
}
现在找到了感兴趣的指示器,您应该尝试连接到它。为此请调用- (void)connectSuccess:(ConnectToPeripheralSuccess)success failure:(ConnectToPeripheralFailure)failure;
在成功连接到外围设备时,将调用第一个块并返回连接到的公关,如果在连接外围设备过程中有任何问题,将调用失败块以及错误。
[peripheral connectSuccess:^(CBPeripheral *peripheral) {
NSLog(@"Connected to peripheral '%@'", [peripheral name]);
}
failure:^(CBPeripheral *peripheral, NSError *error) {
NSLog(@"Failed connecting to Peripheral '%@'. Error : %@", [peripheral name], [error localizedDescription]);
}];
现在应该已经连接到外围设备,可以查找连接外围设备的所有服务。调用- (void)discoverServices:(NSArray *)services success:(DidDiscoverServicesSuccess)success failure:(DidDiscoverServicesFailure)failure;
和scanForPeripheralsWithServices
方法一样,它接受CBUUID
数组。如果提供,它将仅发现具有给定CBUUID
的服务。如果是nil
,则将搜索该外围设备的所有服务。
在发现连接外围设备的所有服务时,将调用第一个块。如果为'discoverServices'参数提供了数组,则这将是一个过滤后的数组,仅显示具有数组中给出的CBUUIDs的服务。
如果存在问题,将使用错误调用失败块。
//Discover the services for the newly connected peripheral
[selectedPeripheral discoverServices:nil //If an array of CBUUIDs is given it will only attempt to discover services with these CBUUIDs
success:^(NSArray *discoveredServices) {
NSLog(@"Services found %@", discoveredServices);
}
failure:^(NSError *error) {
NSLog(@"Error discovering services for peripheral '%@'", [peripheral name]);
}];
每个服务都有一个或多个特征,现在需要找到它们。为此,在CBService上调用- (void)discoverCharacteristics:(NSArray *)characteristics success:(DidDiscoverCharacteristicsForServiceSuccess)success failure:(DidDiscoverCharacteristicsForServiceFailure)failure;
方法。
和其他发现方法一样,它需要一个包含 CBUUID
的数组。如果提供了,它只会在给定的 CBUUID
中查找特征。如果它是 nil
,则搜索该服务的所有特征。
第二个参数是一个块,当找到特征时会调用该块。块中返回的是 CBCharacteristics 数组。
最后一个参数是失败块,无论因为什么原因,都会将 NSError 返回到块中。
[service discoverCharacteristics:nil //If an array of CBUUIDs is given it will only look for the services with that CBUUID
success:^(NSArray *discoveredCharacteristics) {
NSLog(@"Characteristics found: %@", discoveredCharacteristics);
}
failure:^(NSError *error) {
NSLog(@"Error discovering characteristics: %@", [error localizedDescription]);
}];
现在你已经找到了感兴趣的特征,你可以通过首先订阅所选特征的更改来读取其值。为此,设置 CBCharacteristic 的 didUpdateValueBlock。
这个块将返回 NSData,然后可以使用父类方法 hexString
将其转换为十六进制字符串。然后,可以使用 ASCIIStringFromHexString
分类方法将十六进制字符串转换为 ASCII 表示。
[characteristic setDidUpdateValueBlock:^(NSData *updatedValue) {
NSString *hexString = [updatedValue hexString];
NSLog(@"Hex string value : %@", hexString);
NSString *ASCIIString = [hexString ASCIIStringFromHexString];
NSLog(@"String from Hex value : %@", ASCIIString);
dispatch_sync(dispatch_get_main_queue(), ^{
//Perform any UI changes on the main thread
});
}];
一旦设置了此块,你需要使用 readValue
方法从特征中请求值。
[characteristic readValue];
返回的值将返回到 didUpdateValueBlock,并可以从中处理。
就是这样,你现在应该能够发现所需的一切并读取值。对于订阅服务的测试也在进行中,同时写入特征,因为我还在构建外围管理器部分。
twitter : @ste_prescott
本项目在 MIT 许可下提供。
版权 (C) 2014 Ste Prescott
特此授予任何获得本软件及相关文档文件(“软件”)副本的人无限制地处理软件的权利,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本书的权利,并允许提供给软件的人这样做,前提是以下条件
上述版权声明和此许可声明应包含在软件的所有副本或主要部分中。
软件按“原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性、针对特定目的的适用性和非侵权性保证。在任何情况下,作者或版权持有者不对任何索赔、损害或其他责任负责,无论是基于合同、侵权或其他行为,源于、源于或与软件及其使用或其他交易有关。