CoreBluetooth Central模式 Swift版
也是醉了,CB这个API到现在也没有Swift的文档。最新的文档还是3年前还是4年前的OC版的,被雷的外焦里嫩的。自己一点一点写成Swift还各种报错,最坑的是这些错误压根找不到解决方案。索性自己做个个人专用的蓝牙通信库,顺便梳理下这一块。这篇博文讲中心模式
基本
//----------------------------------------------------------------------------------
首先设置代理类
class CentralManagerPro:
NSObject,
CBCentralManagerDelegate
创建中心设备管理器
centralManager = CBCentralManager(delegate:
self, queue: nil,
options: nil)
delegate就是处理中心设备管理器相关事件的,继承CBCentralManagerDelegate的一系列方法全部写在里面。这里就是self,也就是这个管理器所在的类
特别注意,这个中心设备管理器不要重复生成。不然会报错,而且上网搜也没有解决方法。我就为此花了老半天。
开始扫描
if
centralManager.state
== .poweredOn {
centralManager.scanForPeripherals(withServices:
nil, options:
nil)
return true
}else {
return false
}
虽然网上没有任何资料这么写,但是目前新版本里如果不判断中心设备是否开启就直接进行活动会报错。下面所有函数相同
这里的withServices是周边设备内部需要有的服务,如果不指定那所有搜索到的周边设备都会反馈
扫描到以后为了省电,停止扫描
centralManager.stopScan()
连接扫描到的设备
if peripheral !=
nil {
centralManager.connect(peripheral,
options: nil)
return true
}else {
return false
}
连接成功呼出func centralManager(_ central: CBCentralManager,
didConnect
peripheral: CBPeripheral)
连接失败呼出func centralManager(_ central: CBCentralManager,
didFailToConnect
peripheral: CBPeripheral,
error: Error?)
搜索服务和特征
搜索连接上的周边设备有的服务
if peripheral !=
nil {
peripheral.discoverServices(serviceUUIDs)
}
这样的好处是防止搜索以及实效的周边设备,避免程序崩溃
搜索到以后会自动呼出func peripheral(_ peripheral: CBPeripheral,
didDiscoverServices error: Error?)
搜索到自己要的服务以后,进一步搜索自己要的特性
peripheral.discoverCharacteristics(characteristicUUIDs,
for: service)
搜索完成后会呼出 func peripheral(_ peripheral: CBPeripheral,
didDiscoverCharacteristicsFor
service: CBService,
error: Error
搜索到特性后,获取特性的值
peripheral.readValue(for:
char)
获得了值后会自动呼出如下函数 func peripheral(_ peripheral: CBPeripheral,
didUpdateValueFor
characteristic: CBCharacteristic, error: Error?)
改写特性的值
peripheral.writeValue(data, for: char, type:
CBCharacteristicWriteType.withoutResponse)
CBCharacteristicWriteType.withoutResponse这样设置后自己会运行
服务的特性的值被改写后会自动呼出如下函数
(CBCharacteristicWriteType.withoutResponse这样设置后)
//didWriteValueFor
func peripheral(_
peripheral: CBPeripheral,
didWriteValueFor characteristic:
CBCharacteristic, error:
Error?) {
if let
error = error {
print("Write失敗...error:
\(error)")
return
}
print("Write成功!")
}
获取特性值的更新通知
peripheral.setNotifyValue(true, for:
char)
不获取特性值的更新通知
peripheral.setNotifyValue(false,
for: char)
状态更新后会自动呼出如下函数func peripheral(_ peripheral: CBPeripheral,
didUpdateNotificationStateFor
characteristic: CBCharacteristic,
error: Error?)
回调函数(继承协议)
//----------------------------------------------------------------------------------
//-------------------------------------------------------------------
//
CBCentralManagerDelegate
//-------------------------------------------------------------------
///didDiscover
func centralManager(_ central: CBCentralManager,
didDiscover
peripheral: CBPeripheral,
advertisementData:
[String : Any],
rssi RSSI: NSNumber)
{
let state
= "discoverd
peripheral: \(peripheral.services)\n"
print(state)
self.peripheral =
peripheral
}
连接结果
//didConnect
func centralManager(_
central: CBCentralManager,
didConnect peripheral: CBPeripheral)
{
let state =
"central: connected!\n"
print(state)
}
//didFailToConnect
func centralManager(_
central: CBCentralManager,
didFailToConnect peripheral:
CBPeripheral, error:
Error?) {
let state =
"central: failed to connected\n"
print(state)
}
//-------------------------------------------------------------------
//
CBPeripheralDelegate
//-------------------------------------------------------------------
搜索服务完毕后会自动呼出如下函数
//didDiscoverServices
func peripheral(_
peripheral: CBPeripheral,
didDiscoverServices error: Error?)
{
guard let
services = peripheral.services
else{
print("error")
return
}
print("\(services.count)個のサービスを発見。\(services)")
}
搜索完指定服务的特性后会呼出如下函数
//didDiscoverCharacteristicsFor
func peripheral(_
peripheral: CBPeripheral,
didDiscoverCharacteristicsFor service:
CBService, error:
Error?) {
if let
error = error {
print("error:
\(error)")
return
}
let characteristics =
service.characteristics
print("Found
\(characteristics?.count
?? 0) characteristics! :
\(characteristics)")
}
获取指定的特性的值时会呼出如下函数
//didUpdateValueFor
func peripheral(_
peripheral: CBPeripheral,
didUpdateValueFor characteristic:
CBCharacteristic, error:
Error?) {
if let
error = error {
print("Failed... error:
\(error)")
return
}
print("Succeeded! service
uuid:
\(characteristic.service.uuid),
characteristic uuid:
\(characteristic.uuid),
value:
\(characteristic.value)")
}
服务的特性的值被改写后会自动呼出如下函数
(CBCharacteristicWriteType.withoutResponse这样设置后)
//didWriteValueFor
func peripheral(_ peripheral: CBPeripheral,
didWriteValueFor
characteristic: CBCharacteristic,
error: Error?)
{
if let error
= error {
print("Write失敗...error: \(error)")
return
}
print("Write成功!")
}
状态更新后会自动呼出如下函数
//didUpdateNotificationStateFor
func peripheral(_
peripheral: CBPeripheral,
didUpdateNotificationStateFor characteristic:
CBCharacteristic, error:
Error?) {
if let
error = error {
print("Notify状態更新失敗...error:
\(error)")
} else {
print("Notify状態更新成功!
isNotifying:
\(characteristic.isNotifying)")
}
}
CoreBluetooth Central模式 Swift版的更多相关文章
- Swift版iOS游戏框架Sprite Kit基础教程下册
Swift版iOS游戏框架Sprite Kit基础教程下册 试读下载地址:http://pan.baidu.com/s/1qWBdV0C 介绍:本教程是国内唯一的Swift版的Spritekit教程. ...
- Swift版音乐播放器(简化版),swift音乐播放器
这几天闲着也是闲着,学习一下Swift的,于是到开源社区Download了个OC版的音乐播放器,练练手,在这里发扬开源精神, 希望对大家有帮助! 这个DEMO里,使用到了 AudioPlayer(对音 ...
- 快速排序OC、Swift版源码
前言: 你要问我学学算法在工作当中有什么用,说实话,当达不到那个地步的时候,可能我们不能直接的感觉到它的用处!你就抱着这样一个心态,当一些APP中涉及到算法的时候我不想给其他人画界面!公司的项目也是暂 ...
- iOS可视化动态绘制八种排序过程(Swift版)
前面几篇博客都是关于排序的,在之前陆陆续续发布的博客中,我们先后介绍了冒泡排序.选择排序.插入排序.希尔排序.堆排序.归并排序以及快速排序.俗话说的好,做事儿要善始善终,本篇博客就算是对之前那几篇博客 ...
- swift版的CircleView
swift版的CircleView 效果图 源码 // // CircleView.swift // CircleView // // Created by YouXianMing on 15/10/ ...
- swift版的GCD封装
swift版的GCD封装 说明 本人针对swift封装了GCD,包括GCDQueue,GCDGroup,GCDTimer以及GCDSemaphore,使用较为便利. 源码 https://github ...
- swift版的StringAttribute
swift版的StringAttribute 效果 源码 https://github.com/YouXianMing/Swift-StringAttribute // // StringAttrib ...
- swift版的元组
swift版的元组 说明 元组的内容并不多,使用的话跟普通变量类似,以下是测试源码: // // ViewController.swift // Tuples // // Created by You ...
- swift版的枚举变量
swift版的枚举变量 swift的枚举类型跟普通的类是极为类似的,使用的时候,请不要以为他是一个常量,以下是测试用源码 // // ViewController.swift // SwiftEnum ...
随机推荐
- 使用图片作为textview组件的背景
<TextView android:layout_gravity="center" android:layout_width="100dp" androi ...
- 转:使用 SCons 轻松建造程序
转: https://www.ibm.com/developerworks/cn/linux/l-cn-scons/ 在软件项目开发过程中,make 工具通常被用来建造程序.make 工具通过一个被称 ...
- Java 实现 淘宝秒杀 聚划算 自己主动提醒 源代码
说明 本实例可以监控聚划算的抢购button,在聚划算整点聚的时间到达时自己主动弹开页面(URL自定义). 能够自己定义监控持续分钟数,同一时候还能够通过多线程加快刷新速度. 源代码 package ...
- react 创建组件 (三)PureComponet
我们知道,当组件的props或者state发生变化的时候:React会对组件当前的Props和State分别与nextProps和nextState进行比较,当发现变化时,就会对当前组件以及子组件进行 ...
- 在java中String类为什么要设计成final?
大神链接:在java中String类为什么要设计成final? - 程序员 - 知乎 我进行了重新排版,并且更换了其中的一个例子,让我们更好理解. String很多实用的特性,比如说“不可变性”,是工 ...
- ngnix
nginx的平滑重启 博客分类: nginx nginx平滑重启 在研发过程中,修改nginx的配置文件nginx.conf是很平常的事,需要重启nginx.如果我们直接reload是有一定风险的, ...
- 常量,字段,构造方法 调试 ms 源代码 一个C#二维码图片识别的Demo 近期ASP.NET问题汇总及对应的解决办法 c# chart控件柱状图,改变柱子宽度 使用C#创建Windows服务 C#服务端判断客户端socket是否已断开的方法 线程 线程池 Task .NET 单元测试的利剑——模拟框架Moq
常量,字段,构造方法 常量 1.什么是常量 常量是值从不变化的符号,在编译之前值就必须确定.编译后,常量值会保存到程序集元数据中.所以,常量必须是编译器识别的基元类型的常量,如:Boolean ...
- Qt linux文件同步写入
因为linux 系统机制问题,文件的创建和写入并不会直接写入硬盘.而是先写入缓存,当系统要关闭或须要时才写入硬盘.为防止突然掉电,应将缓存中的文件及时同步到硬盘上去. linux 下的sync 命令具 ...
- 该项目不在c:\ 请确认该项目的位置
该项目不在c:\ 请确认该项目的位置 - CSDN博客https://blog.csdn.net/feilong1lantern/article/details/50388414 在删除不掉的文件夹目 ...
- 搭建java运行环境
安装IDE 集成开发环境(IDE,Integrated Development Environment ) 1.安装jdk,jre(jdk自带jre),记住他们的安装位置. 2.配置环境变量.(JAV ...