iOS蓝牙开发
<p></p><div class="toc"><div class="toc-container-header">目录</div><ul><li>一、框架<ul><li>包含类</li><li>申请权限</li></ul></li><li>二、中心开发模式<ul><li>初始化</li><li>扫描外围设备</li><li>扫描结果回调<ul><li>蓝牙状态监听</li><li>发现设备回调</li></ul></li><li>连接设备</li><li>连接结果回调<ul><li>设备连接成功</li><li>连接失败</li><li>连接断开</li></ul></li><li>扫描外围设备的服务</li><li>扫描结果回调</li><li>查询服务的特征</li><li>发现服务特征回调</li><li>注册特征</li><li>特征注册结果回调</li><li>通过特征读取数据</li><li>通过特征发送数据</li><li>发送数据结果回调</li><li>关闭蓝牙设备</li></ul></li></ul></div><p></p><h2 id="一框架">一、框架</h2>
<p>基于 <CoreBluetooth/CoreBluetooth.h> 框架</p>
<pre><code>不要试图继承CoreBluetooth中的任何类,因为重载会导致未知的结果
</code></pre>
<blockquote>
<p>有两种开发方案,一种是以本地作为中心设备,一种是已远端设备作为中心设备</p>
</blockquote>
<h3 id="包含类">包含类</h3>
<p><code>外围设备</code>:通常用于发布服务、生成数据、保存数据。外围设备发布并广播服务,告诉周围的中央设备它的可用服务特征</p>
<p><code>中心设备</code>:中心设备扫描到外围设备后会视图建立连接,连接成功后可用使用外围设备的服务和特征</p>
<p><code>外围设备</code>和<code>中心设备</code>直接交换的桥梁是服务(<code>CBService</code>)和特征(<code>CBCharacteristic</code>),二者都拥有一个唯一的标识(<code>CBUUID</code>)来确定唯一的服务和特征。每个服务可以有多个特征。</p>
<ul>
<li>
<p>CBPeripheral 外围设备</p>
</li>
<li>
<p>CBPeripheralManager 外围设备管理类</p>
</li>
<li>
<p>CBMutableService 外围设备的服务</p>
</li>
<li>
<p>CBMutableCharacteristic 外围设备的特征</p>
</li>
<li>
<p>CBUUID 外围设备服务特征的唯一标志</p>
</li>
<li>
<p>CBCentral 中心设备</p>
</li>
<li>
<p>CBCentralManager 中心设备管理类</p>
</li>
<li>
<p>CBService 外围设备的服务</p>
</li>
<li>
<p>CBCharacteristic 外围设备的特征</p>
</li>
<li>
<p>CBATTRequest 中心设备读写数据的请求</p>
</li>
</ul>
<h3 id="申请权限">申请权限</h3>
<p>iOS 10以后,所有的蓝牙开发都要申请蓝牙权限,在项目的info.plist中设置<code>NSBluetoothPeripheralUsageDescription</code>,对应的key为<code>Privacy - Bluetooth Always Usage Description</code>和<code>Privacy - Bluetooth Peripheral Usage Description</code></p>
<h2 id="二中心开发模式">二、中心开发模式</h2>
<p>以中心设备CBCentral作为本地,外网设备CBPeripheral作为远端</p>
<h3 id="初始化">初始化</h3>
<pre><code>// 初始化选项,设置YES时,如果用户蓝牙关闭,会弹出一个提示框
NSDictionary *options = @{CBCentralManagerOptionShowPowerAlertKey: @YES};
CBCentralManager* tM = [ initWithDelegate:self queue:dispatch_get_main_queue() options:options];
self.cbcManager = tM;
</code></pre>
<h3 id="扫描外围设备">扫描外围设备</h3>
<pre><code>//判断当前蓝牙工作状态是否开启
if (self.cbcManager.state == CBManagerStatePoweredOn) {
//记录当前过滤条件
self.fliterName = fliterName;
//优先查找系统已经连接上的PV蓝牙设备
self.sysConnectArrs = ]];
for (CBPeripheral * cbp in self.sysConnectArrs) {
;
}
//开始搜索设备
NSDictionary * option = @{
// CBCentralManagerScanOptionAllowDuplicatesKey 指示是否过滤重复情况
CBCentralManagerScanOptionAllowDuplicatesKey:,
// 蓝牙未开启情况下是否显示提示框
CBCentralManagerOptionShowPowerAlertKey:@0
};
// services和option都可以传nil
// services传对应的UUIDstring则扫描指定id的设备
] options:option];
}
else{
// TODO:返回蓝牙未打开状态
}
</code></pre>
<h3 id="扫描结果回调">扫描结果回调</h3>
<h4 id="蓝牙状态监听">蓝牙状态监听</h4>
<pre><code>- (void)centralManagerDidUpdateState:(nonnull CBCentralManager *)central {
switch (central.state) {
case CBManagerStateUnknown:
NSLog(@">>>CBCentralManagerStateUnknown");
break;
case CBManagerStateResetting:
NSLog(@">>>CBCentralManagerStateResetting");
break;
case CBManagerStateUnsupported:
NSLog(@">>>CBCentralManagerStateUnsupported");
break;
case CBManagerStateUnauthorized:
NSLog(@">>>CBCentralManagerStateUnauthorized");
break;
case CBManagerStatePoweredOff:
NSLog(@">>>CBCentralManagerStatePoweredOff");
{
//手动断开设备连接
for (NSString * pcDeviceName in self.connectedDeviceMap) {
PVBluetoothDevice * device = self.connectedDeviceMap;
;
}
}
break;
case CBManagerStatePoweredOn:
{
NSLog(@">>>CBCentralManagerStatePoweredOn");
}
break;
default:
break;
}
if (self.delegate && ) {
;
}
}
</code></pre>
<h4 id="发现设备回调">发现设备回调</h4>
<pre><code>//搜索到设备
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI{
//通过名称过滤设备是否为过滤设备
for (NSString * fliter in self.fliterName) {
if () {
;
//把系统扫描出来的一起回调
;
if (self.delegate && ){
//查看下新搜索出来的设备系统是不是已经连接了
NSArray * sysconnectedDeviceArr = ]];
BOOL sysConnected = ;
;
}
}
}
}
</code></pre>
<h3 id="连接设备">连接设备</h3>
<pre><code>//CBConnectPeripheralOptionNotifyOnConnectionKey 表示应用被挂起时,系统应该为给定的外设显示警报
}];
</code></pre>
<h3 id="连接结果回调">连接结果回调</h3>
<h4 id="设备连接成功">设备连接成功</h4>
<pre><code>//
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
;
//开始搜索服务
]];
}
</code></pre>
<h4 id="连接失败">连接失败</h4>
<pre><code>//连接失败
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
NSLog(@"%@",error.localizedDescription);
}
</code></pre>
<h4 id="连接断开">连接断开</h4>
<pre><code>-(void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
NSLog(@"设备断开");
;
}
</code></pre>
<h3 id="扫描外围设备的服务">扫描外围设备的服务</h3>
<pre><code>//uuid需要约定好
]];
</code></pre>
<h3 id="扫描结果回调-1">扫描结果回调</h3>
<pre><code>//发现服务服务
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
for (CBService * service in peripheral.services) {
if () {//确定串口服务
这里查找特征
}
}
</code></pre>
<h3 id="查询服务的特征">查询服务的特征</h3>
<pre><code>//开始查找特征
;
</code></pre>
<h3 id="发现服务特征回调">发现服务特征回调</h3>
<pre><code>//发现特征
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
for (CBCharacteristic *characteristic in service.characteristics) {
// 遍历获取对应的特征值
// 获取约定的发送特征
if () {
BluetoothDevice * device = self.connectedDeviceMap;
device.sendCharacteristic = characteristic;
}
// 获取约定的接收特征
else if (){
BluetoothDevice * device = self.connectedDeviceMap;
device.receivedCharacteristic = characteristic;
;
}
/**a
-- 当发现characteristic有descriptor,回调didDiscoverDescriptorsForCharacteristic
*/
;
}
}
</code></pre>
<h3 id="注册特征">注册特征</h3>
<pre><code>// 注册了特征值后,就可以通过特征值来读取数据了。
;
</code></pre>
<h3 id="特征注册结果回调">特征注册结果回调</h3>
<pre><code>- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error;
</code></pre>
<h3 id="通过特征读取数据">通过特征读取数据</h3>
<pre><code>//收到数据
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
NSLog(@"%@",characteristic.value);
if (self.delegate && ) {
;
}
}
</code></pre>
<h3 id="通过特征发送数据">通过特征发送数据</h3>
<p>type有两个值:</p>
<ul>
<li>CBCharacteristicWriteWithResponse 需要返回发送数据的结果</li>
<li>CBCharacteristicWriteWithoutResponse不需要返回发送数据的结果</li>
</ul>
<pre><code>;
</code></pre>
<h3 id="发送数据结果回调">发送数据结果回调</h3>
<p>如果需要返回发送结果,会调用当前回调</p>
<pre><code>- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
NSLog(@"数据发送成功");
}
</code></pre>
<h3 id="关闭蓝牙设备">关闭蓝牙设备</h3>
<pre><code>- (void)closeBlueTooth {
//停止扫描
;
if (self.peripheral) {
//断开当前的连接
;
}
self.centralManager = nil;
self.peripheral = nil;
self.characteristic = nil;
}
</code></pre><br><br>
来源:https://www.cnblogs.com/absty-guo/p/14242215.html
頁:
[1]