您好,欢迎来到微智科技网。
搜索
您的当前位置:首页iOS蓝牙开发详解(基本知识、相关类图、交互流程)

iOS蓝牙开发详解(基本知识、相关类图、交互流程)

来源:微智科技网
iOS蓝⽛开发详解(基本知识、相关类图、交互流程)

本⽂从以下三⽅⾯讲解下蓝⽛开发1、蓝⽛相关基本知识2、蓝⽛相关类图3、蓝⽛交互流程

⼀、蓝⽛相关基本知识

涉及到蓝⽛开发,⾸先有⼏个问题是需要我们理解的

1、任何设备既可以是中⼼设备、也可以是外围设备

2、外设 和 中⼼设备 之间通过特征建⽴⼀个双向的数据通道

3、CBCentralManager主要操作中⼼设备,处理链接上外设之前的操作,链接上外设后,主要靠CBPeripheral(主要操作外设)处理外设相关操作(服务、特征、数据读写)

4、中⼼设备管理 CBCentralManager

中⼼控制类,主要管理中⼼设备,以及处理跟外设(外围设备)相关操作,主要是扫描、链接、断开外设。操作中⼼设备的核⼼类。

很重要的协议CBCentralManagerDelegate,包含中⼼设备状态(是否打开蓝⽛)回调、发现外设回调、链接外设成功回调、链接外设失败回调、外设链接断开回调等⽅法。

⼀个中⼼设备可以链接多个外围设备。

5、外围设备 CBPeripheral

外设类,包含设备的基础属性,名字,uuid等信息。向外设写⼊数据。当中⼼设备连接到外设后,需要通过外设对象的代理⽅法进⾏数据交互。操作外围设备的核⼼类。

很重要的协议CBPeripheralDelegate,包含发现服务回调、发现特征回调、特征的通知设置改变回调、特征更新回调、特征已写⼊数据回调等⽅法。⼀个设备包含多个服务、⼀个服务包含多个特征、⼀个特征⼜包含多个描述。

6、外围设备管理 CBPeripheralManager

设备的控制,主要可以为设备设置Service以及Characteristic,可以⼿动配置特定的服务和特征值,也可看作可以⾃定义蓝⽛协议,例如将⼿机作为外设时可以为⾃⼰的⼿机蓝⽛设置服务和特征值。CBCentralManager更适合将⾃⼰的软件作为中⼼。⽤的较少

7、服务 CBService

服务对象是⽤来管理外设提供的⼀些数据服务的。⼀个服务可以包含多个特征

8、特征 CBCharacteristic

通过绑定服务中的特征值来进⾏数据的读写操作。特征就是具体键值对,提供数据的地⽅。

每个特征属性分为这么⼏种:读,写,通知等⼏种⽅式。

有时读、写、通知可以是同⼀个特征,也可以读、写、通知各⽤⼀个特征表⽰。⼀个特征可以包含多个描述。⼀般我们操作到特征这⼀层

9、描述 CBDescriptor

每个characteristic可以对应⼀个或多个Description 供⽤户描述characteristic的信息或属性。

10、CBAttribute

CBService,CBCharacteristic,CBDescriptor 类都继承⾃ CBAttribute,它们有⼀个共同的属性 CBUUID,⽤来作为唯⼀的标识。

⼆、蓝⽛相关类图

下⾯⽤类图简述下:

⼀个中⼼设备可以连接多个外设,⼀个外设包含多个服务,⼀个服务包含多个特征,⼀个特征包含多个描述服务、特征、描述都⽤CBUUID唯⼀标识

三、蓝⽛交互流程

下⾯简述下以⼿机作为中⼼设备、其它作为外围设备的交互流程,⼤致流程如图所⽰下⾯是操作详解

1、创建中⼼设备管理对象(初始化中⼼设备)

CBCentralManager 的创建是异步的,如果初始化完成之后没有被当前创建它的类所持有,就会在下⼀次 RunLoop 迭代的时候释放。创建线程写nil,为主线程。

初始化成功后,就会触发 CBCentralManagerDelegate 中的中⼼设备状态更新⽅法:centralManagerDidUpdateState:

NSDictionary *options = @{CBCentralManagerOptionShowPowerAlertKey:@NO};

self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:options];

/*!

* @method initWithDelegate:queue:options: *

* @param delegate The delegate that will receive central role events.

* @param queue The dispatch queue on which the events will be dispatched. * @param options An optional dictionary specifying options for the manager. *

* @discussion The initialization call. The events of the central role will be dispatched on the provided queue. * If nil, the main queue will be used. *

* @seealso CBCentralManagerOptionShowPowerAlertKey * @seealso CBCentralManagerOptionRestoreIdentifierKey * */

- (instancetype)initWithDelegate:(nullable id)delegate queue:(nullable dispatch_queue_t)queue

options:(nullable NSDictionary *)options NS_AVAILABLE(10_9, 7_0) NS_DESIGNATED_INITIALIZER;@protocol CBCentralManagerDelegate @required

/*!

* @method centralManagerDidUpdateState: *

* @param central The central manager whose state has changed. *

* @discussion Invoked whenever the central manager's state has been updated. Commands should only be issued when the state is * CBCentralManagerStatePoweredOn. A state below CBCentralManagerStatePoweredOn * implies that scanning has stopped and any connected peripherals have been disconnected. If the state moves below * CBCentralManagerStatePoweredOff, all CBPeripheral objects obtained from this central * manager become invalid and must be retrieved or discovered again. *

* @see state * */

- (void)centralManagerDidUpdateState:(CBCentralManager *)central;

2、扫描外围设备

在CBCentralManagerDelegate 中的中⼼设备状态更新⽅法:centralManagerDidUpdateState:中,

当中⼼设备处于CBManagerStatePoweredOn 状态的时候开始扫描周边设备(可以使⽤指定的 UUID 发现特定的 Service,也可以传⼊ nil,表⽰发现所有周边的蓝⽛设备,不过还是建议只发现⾃⼰需要服务的设备)。

扫描外设:scanForPeripheralsWithServices:options:

该操作由CBCentralManager对象通过scanForPeripheralsWithServices:options:⽅法实现

case CBManagerStatePoweredOn: //蓝⽛正常开启 [self startScan]; break;

- (void)startScan {

// [self.centralManager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @YES }];// 扫描所有设备 当指定设备不好使时可以使⽤该⽅法

// [self.centralManager scanForPeripheralsWithServices:nil options:nil];// 扫描指定设备 快速

[self.centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:self.peripheralServiceUUID]] options:nil];

[self startTime];}

/*!

* @method scanForPeripheralsWithServices:options: *

* @param serviceUUIDs A list of CBUUID objects representing the service(s) to scan for. * @param options An optional dictionary specifying options for the scan. *

* @discussion Starts scanning for peripherals that are advertising any of the services listed in serviceUUIDs. Although strongly discouraged, * if serviceUUIDs is nil all discovered peripherals will be returned. If the central is already scanning with different * serviceUUIDs or options, the provided parameters will replace them.

* Applications that have specified the bluetooth-central background mode are allowed to scan while backgrounded, with two

* caveats: the scan must specify one or more service types in serviceUUIDs, and the CBCentralManagerScanOptionAllowDuplicatesKey * scan option will be ignored. *

* @see centralManager:didDiscoverPeripheral:advertisementData:RSSI: * @seealso CBCentralManagerScanOptionAllowDuplicatesKey

* @seealso CBCentralManagerScanOptionSolicitedServiceUUIDsKey * */

- (void)scanForPeripheralsWithServices:(nullable NSArray *)serviceUUIDs options:(nullable NSDictionary *)options;

3、发现外围设备

CBCentralManager对象执⾏扫描外设⽅法scanForPeripheralsWithServices:options:后

会触发 CBCentralManagerDelegate 中的⽅法:(发现外设)centralManager:didDiscoverPeripheral:advertisementData:RSSI:

如果在扫描时指定了明确的服务,那么此时该⽅法⾥的外设就是包含该服务的外设,如果传⼊的是nil,那么此时该⽅法⾥的外设就是周边所有打开的蓝⽛设备。

/*!

* @method centralManager:didDiscoverPeripheral:advertisementData:RSSI: *

* @param central The central manager providing this update. * @param peripheral A CBPeripheral object.

* @param advertisementData A dictionary containing any advertisement and scan response data.

* @param RSSI The current RSSI of peripheral, in dBm. A value of 127 is reserved and indicates the RSSI * was not available. *

* @discussion This method is invoked while scanning, upon the discovery of peripheral by central. A discovered peripheral must * be retained in order to use it; otherwise, it is assumed to not be of interest and will be cleaned up by the central manager. For * a list of advertisementData keys, see {@link CBAdvertisementDataLocalNameKey} and other similar constants. *

* @seealso CBAdvertisementData.h * */

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI;

4、链接外设

在CBCentralManagerDelegate 中的发现外设⽅法:centralManager:didDiscoverPeripheral:advertisementData:RSSI:中,我们会链接外设:connectPeripheral:options:

该操作由CBCentralManager对象通过connectPeripheral:options:⽅法实现

我们通过名称或者⼚商数据来确定我们需要链接的外设(过滤外设),找到后停⽌扫描,然后链接该外设,即链接指定外设

[central connectPeripheral:peripheral options:nil];

/*!

* @method connectPeripheral:options: *

* @param peripheral The CBPeripheral to be connected.

* @param options An optional dictionary specifying connection behavior options. *

* @discussion Initiates a connection to peripheral. Connection attempts never time out and, depending on the outcome, will result * in a call to either {@link centralManager:didConnectPeripheral:} or {@link centralManager:didFailToConnectPeripheral:error:}.

* Pending attempts are cancelled automatically upon deallocation of peripheral, and explicitly via {@link cancelPeripheralConnection}. *

* @see centralManager:didConnectPeripheral:

* @see centralManager:didFailToConnectPeripheral:error: * @seealso CBConnectPeripheralOptionNotifyOnConnectionKey * @seealso CBConnectPeripheralOptionNotifyOnDisconnectionKey * @seealso CBConnectPeripheralOptionNotifyOnNotificationKey * @seealso CBConnectPeripheralOptionEnableTransportBridgingKey * @seealso CBConnectPeripheralOptionRequiresANCS * */

- (void)connectPeripheral:(CBPeripheral *)peripheral options:(nullable NSDictionary *)options;

5、链接外设结果回调

CBCentralManager对象执⾏链接外设⽅法connectPeripheral:options:后会触发 CBCentralManagerDelegate 中的⽅法:

链接外设成功回调:centralManager:didConnectPeripheral:

/*!

* @method centralManager:didConnectPeripheral: *

* @param central The central manager providing this information.

* @param peripheral The CBPeripheral that has connected. *

* @discussion This method is invoked when a connection initiated by {@link connectPeripheral:options:} has succeeded. * */

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral;

链接外设失败回调:centralManager:didFailToConnectPeripheral:error:

/*!

* @method centralManager:didFailToConnectPeripheral:error: *

* @param central The central manager providing this information.

* @param peripheral The CBPeripheral that has failed to connect. * @param error The cause of the failure. *

* @discussion This method is invoked when a connection initiated by {@link connectPeripheral:options:} has failed to complete. As connection attempts do not * timeout, the failure of a connection is atypical and usually indicative of a transient issue. * */

- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error;

6、查找服务

在CBCentralManagerDelegate 中的链接外设成功回调⽅法:centralManager:didConnectPeripheral:中,我们会查找服务:discoverServices:

该操作由CBPeripheral对象通过discoverServices:⽅法实现

[peripheral discoverServices:@[[CBUUID UUIDWithString:self.peripheralServiceUUID]]];

/*!

* @method discoverServices: *

* @param serviceUUIDs A list of CBUUID objects representing the service types to be discovered. If nil, * all services will be discovered. *

* @discussion Discovers available service(s) on the peripheral. *

* @see peripheral:didDiscoverServices: */

- (void)discoverServices:(nullable NSArray *)serviceUUIDs;

7、发现服务

CBPeripheral对象执⾏查找服务⽅法discoverServices:后,

会触发 CBPeripheralDelegate 中的发现服务⽅法:peripheral:didDiscoverServices:

/*!

* @method peripheral:didDiscoverServices: *

* @param peripheral The peripheral providing this information. * @param error If an error occurred, the cause of the failure. *

* @discussion This method returns the result of a @link discoverServices: @/link call. If the service(s) were read successfully, they can be retrieved via * peripheral's @link services @/link property. * */

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(nullable NSError *)error;

8、查找特征

在 CBPeripheralDelegate 中的发现服务⽅法:peripheral:didDiscoverServices:中,我们会查找特征:discoverCharacteristics:forService:

该操作由CBPeripheral对象通过discoverCharacteristics:forService:⽅法实现

[peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:self.peripheralCharacteristicRTXUUID]] forService:service];

/*!

* @method discoverCharacteristics:forService: *

* @param characteristicUUIDs A list of CBUUID objects representing the characteristic types to be discovered. If nil, * all characteristics of service will be discovered. * @param service A GATT service. *

* @discussion Discovers the specified characteristic(s) of service. *

* @see peripheral:didDiscoverCharacteristicsForService:error: */

- (void)discoverCharacteristics:(nullable NSArray *)characteristicUUIDs forService:(CBService *)service;

9、发现特征

CBPeripheral对象执⾏查找特征⽅法discoverCharacteristics:forService:后,

会触发CBPeripheralDelegate 中的发现特征⽅法:peripheral:didDiscoverCharacteristicsForService:error:

/*!

* @method peripheral:didDiscoverCharacteristicsForService:error: *

* @param peripheral The peripheral providing this information.

* @param service The CBService object containing the characteristic(s). * @param error If an error occurred, the cause of the failure. *

* @discussion This method returns the result of a @link discoverCharacteristics:forService: @/link call. If the characteristic(s) were read successfully, * they can be retrieved via service's characteristics property. */

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(nullable NSError *)error;

10、写特征、通知特征(读取)、读特征

在 CBPeripheralDelegate 中的发现特征⽅法:peripheral:didDiscoverCharacteristicsForService:error:中,我们会处理特征(读、写、通知),⼀般会保存写⼊特征,⽅便后期写⼊数据,打开使能通知,⽅便读取数据写:

保存写特征,⽅便后期写⼊数据。读:

通知特征和读特征都是为了读取,⼀般我们使⽤的都是通知,使⽤通知的时候,要打开使能通知(订阅),

该操作由CBPeripheral对象通过setNotifyValue:forCharacteristic:⽅法打开指定通知特征

通知特征发送的数据在didUpdateValueForCharacteristic⽅法⾥接受(读取)

该操作会回调CBPeripheralDelegate 中的⽅法peripheral:didUpdateNotificationStateForCharacteristic:error:通过characteristic.isNotifying知晓通知状态

/*!

* @method peripheral:didUpdateNotificationStateForCharacteristic:error: *

* @param peripheral The peripheral providing this information. * @param characteristic A CBCharacteristic object. * @param error If an error occurred, the cause of the failure. *

* @discussion This method returns the result of a @link setNotifyValue:forCharacteristic: @/link call. */

- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error;for (CBCharacteristic *characteristic in service.characteristics) {

// if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:self.peripheralCharacteristicTXUUID]]) {

// // 打开使能通知 (订阅)该特征发送的数据在didUpdateValueForCharacteristic⽅法⾥接受(读取)// [peripheral setNotifyValue:YES forCharacteristic:characteristic];

// } else if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:self.peripheralCharacteristicRXUUID]]) {// // 保存外设接受特征(写⼊特征)// self.characteristicRX = characteristic;

11、写⼊数据

写⼊⽅法:writeValue:forCharacteristic:type:

写⼊操作由CBPeripheral对象通过writeValue:forCharacteristic:type:⽅法写⼊指定写⼊特征

[self.peripheral writeValue:peripheralRXData forCharacteristic:self.characteristicRX type: CBCharacteristicWriteWithResponse];

/*!

* @method writeValue:forCharacteristic:type: *

* @param data The value to write.

* @param characteristic The characteristic whose characteristic value will be written. * @param type The type of write to be executed. *

* @discussion Writes value to characteristic's characteristic value.

* If the CBCharacteristicWriteWithResponse type is specified, {@link peripheral:didWriteValueForCharacteristic:error:} * is called with the result of the write request.

* If the CBCharacteristicWriteWithoutResponse type is specified, and canSendWriteWithoutResponse is false, the delivery * of the data is best-effort and may not be guaranteed. *

* @see peripheral:didWriteValueForCharacteristic:error: * @see peripheralIsReadyToSendWriteWithoutResponse: * @see canSendWriteWithoutResponse * @see CBCharacteristicWriteType */

- (void)writeValue:(NSData *)data forCharacteristic:(CBCharacteristic *)characteristic type:(CBCharacteristicWriteType)type;

写⼊数据有两种⽅式:

/*

32 typedef NS_ENUM(NSInteger, CBCharacteristicWriteType) {

33 CBCharacteristicWriteWithResponse = 0,//写数据并且接收成功与否回执34 CBCharacteristicWriteWithoutResponse,//写数据不接收回执35 };36 */

如果写⼊类型为CBCharacteristicWriteWithResponse 回调CBPeripheralDelegate 中的⽅法:peripheral:didWriteValueForCharacteristic:error:,

如果写⼊类型为CBCharacteristicWriteWithoutResponse不回调此⽅法,该⽅法只是告知写⼊数据是否成功

/*!

* @method peripheral:didWriteValueForCharacteristic:error: *

* @param peripheral The peripheral providing this information. * @param characteristic A CBCharacteristic object. * @param error If an error occurred, the cause of the failure. *

* @discussion This method returns the result of a {@link writeValue:forCharacteristic:type:} call, when the CBCharacteristicWriteWithResponse type is used. */

- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error;

写⼊数据后外设响应数据在特征值更新⽅法didUpdateValueForCharacteristic:error:中读取

12、读取数据

读取外设发送给中⼼设备的数据,

⽆论是read的回调,还是notify(订阅)的回调都是CBPeripheralDelegate 中的⽅法:特征值更新:didUpdateValueForCharacteristic:error:

/*!

* @method peripheral:didUpdateValueForCharacteristic:error: *

* @param peripheral The peripheral providing this information. * @param characteristic A CBCharacteristic object. * @param error If an error occurred, the cause of the failure. *

* @discussion This method is invoked after a @link readValueForCharacteristic: @/link call, or upon receipt of a notification/indication. */

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error;

13、断开链接

断开链接:cancelPeripheralConnection:

断开链接操作由CBCentralManager对象通过cancelPeripheralConnection:⽅法实现该⽅法不会触发CBCentralManagerDelegate 中的⽅法:

断开外设(仅在异常断开时会触发):centralManager:didDisconnectPeripheral:error:

/*!

* @method cancelPeripheralConnection: *

* @param peripheral A CBPeripheral. *

* @discussion Cancels an active or pending connection to peripheral. Note that this is non-blocking, and any CBPeripheral * commands that are still pending to peripheral may or may not complete. *

* @see centralManager:didDisconnectPeripheral:error: * */

- (void)cancelPeripheralConnection:(CBPeripheral *)peripheral;

参考资料:

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 7swz.com 版权所有 赣ICP备2024042798号-8

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务