Swift语言iOS8的蓝牙Bluetooth解析
开发中央步骤:
1.添加CoreBluetooth.framework框架到你的工程
2.继承两个协议:CBCentralManagerDelegate和CBPeripheralDelegate
个人写的demo,有详细注释。看不懂的在提出来,这里就不做过多的解释了。
1 //
2 // ViewController.swift
3 // CoreBluetooth
4 //
5 // Created by fanviwa on 15/4/23.
6 // Copyright (c) 2015年 fanviwa. All rights reserved.
7 //
8
9 import UIKit
10
11 class ViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate {
12
13 @IBOutlet weak var tableView: UITableView!
14
15 //添加属性
16 var manager: CBCentralManager!
17 var peripheral: CBPeripheral!
18 var writeCharacteristic: CBCharacteristic!
19 //保存收到的蓝牙设备
20 var deviceList:NSMutableArray = NSMutableArray()
21 //服务和特征的UUID
22 let kServiceUUID = [CBUUID(string:"FFE0")]
23 let kCharacteristicUUID = [CBUUID(string:"FFE1")]
24
25 override func viewDidLoad() {
26 super.viewDidLoad()
27 //1.创建一个中央对象
28 self.manager = CBCentralManager(delegate: self, queue: nil)
29 }
30
31 //2.检查运行这个App的设备是不是支持BLE。代理方法
32 func centralManagerDidUpdateState(central: CBCentralManager){
33 switch central.state {
34 case CBCentralManagerState.PoweredOn:
35 //扫描周边蓝牙外设.
36 //写nil表示扫描所有蓝牙外设,如果传上面的kServiceUUID,那么只能扫描出FFEO这个服务的外设。
37 //CBCentralManagerScanOptionAllowDuplicatesKey为true表示允许扫到重名,false表示不扫描重名的。
38 self.manager.scanForPeripheralsWithServices(kServiceUUID, options:[CBCentralManagerScanOptionAllowDuplicatesKey: false])
39 println("蓝牙已打开,请扫描外设")
40 case CBCentralManagerState.Unauthorized:
41 println("这个应用程序是无权使用蓝牙低功耗")
42 case CBCentralManagerState.PoweredOff:
43 println("蓝牙目前已关闭")
44 default:
45 println("中央管理器没有改变状态")
46 }
47 }
48
49 //3.查到外设后,停止扫描,连接设备
50 //广播、扫描的响应数据保存在advertisementData 中,可以通过CBAdvertisementData 来访问它。
51 func centralManager(central: CBCentralManager!, didDiscoverPeripheral peripheral: CBPeripheral!, advertisementData: [NSObject : AnyObject]!, RSSI : NSNumber!){
52 if(!self.deviceList.containsObject(peripheral)){
53 self.deviceList.addObject(peripheral)
54 }
55 self.tableView.reloadData()
56 }
57
58 //4.连接外设成功,开始发现服务
59 func centralManager(central: CBCentralManager!, didConnectPeripheral peripheral: CBPeripheral!){
60 //停止扫描外设
61 self.manager.stopScan()
62 self.peripheral = peripheral
63 self.peripheral.delegate = self
64 self.peripheral.discoverServices(nil)
65
66 }
67
68 //连接外设失败
69 func centralManager(central: CBCentralManager!, didFailToConnectPeripheral peripheral: CBPeripheral!, error: NSError!){
70 println("连接外设失败===\(error)")
71 }
72
73 //5.请求周边去寻找它的服务所列出的特征
74 func peripheral(peripheral: CBPeripheral!, didDiscoverServices error: NSError!){
75 if error != nil {
76 println("错误的服务特征:\(error.localizedDescription)")
77 return
78 }
79 var i: Int = 0
80 for service in peripheral.services {
81 println("服务的UUID:\(service.UUID)")
82 i++
83 //发现给定格式的服务的特性
84 // if (service.UUID == CBUUID(string:"FFE0")) {
85 // peripheral.discoverCharacteristics(kCharacteristicUUID, forService: service as CBService)
86 // }
87 peripheral.discoverCharacteristics(nil, forService: service as! CBService)
88 }
89 }
90
91 //6.已搜索到Characteristics
92 func peripheral(peripheral: CBPeripheral!, didDiscoverCharacteristicsForService service: CBService!, error: NSError!){
93 //println("发现特征的服务:\(service.UUID.data) == 服务UUID:\(service.UUID)")
94 if (error != nil){
95 println("发现错误的特征:\(error.localizedDescription)")
96 return
97 }
98
99 for characteristic in service.characteristics {
100 //罗列出所有特性,看哪些是notify方式的,哪些是read方式的,哪些是可写入的。
101 println("服务UUID:\(service.UUID) 特征UUID:\(characteristic.UUID)")
102 //特征的值被更新,用setNotifyValue:forCharacteristic
103 switch characteristic.UUID.description {
104 case "FFE1":
105 //如果以通知的形式读取数据,则直接发到didUpdateValueForCharacteristic方法处理数据。
106 self.peripheral.setNotifyValue(true, forCharacteristic: characteristic as! CBCharacteristic)
107
108 case "2A37":
109 //通知关闭,read方式接受数据。则先发送到didUpdateNotificationStateForCharacteristic方法,再通过readValueForCharacteristic发到didUpdateValueForCharacteristic方法处理数据。
110 self.peripheral.readValueForCharacteristic(characteristic as! CBCharacteristic)
111
112 case "2A38":
113 self.peripheral.readValueForCharacteristic(characteristic as! CBCharacteristic)
114
115 case "Battery Level":
116 self.peripheral.setNotifyValue(true, forCharacteristic: characteristic as! CBCharacteristic)
117
118 case "Manufacturer Name String":
119 self.peripheral.readValueForCharacteristic(characteristic as! CBCharacteristic)
120
121 case "6E400003-B5A3-F393-E0A9-E50E24DCCA9E":
122 self.peripheral.setNotifyValue(true, forCharacteristic: characteristic as! CBCharacteristic)
123
124 case "6E400002-B5A3-F393-E0A9-E50E24DCCA9E":
125 self.peripheral.readValueForCharacteristic(characteristic as! CBCharacteristic)
126 self.writeCharacteristic = characteristic as! CBCharacteristic
127 let heartRate: NSString = "ZhuHai XY"
128 let dataValue: NSData = heartRate.dataUsingEncoding(NSUTF8StringEncoding)!
129 //写入数据
130 self.writeValue(service.UUID.description, characteristicUUID: characteristic.UUID.description, peripheral: self.peripheral, data: dataValue)
131
132 default:
133 break
134 }
135 }
136 }
137
138 //8.获取外设发来的数据,不论是read和notify,获取数据都是从这个方法中读取。
139 func peripheral(peripheral: CBPeripheral!, didUpdateValueForCharacteristic characteristic: CBCharacteristic!, error: NSError!){
140 if(error != nil){
141 println("发送数据错误的特性是:\(characteristic.UUID) 错误信息:\(error.localizedDescription) 错误数据:\(characteristic.value)")
142 return
143 }
144
145
146
147 switch characteristic.UUID.description {
148 case "FFE1":
149 println("=\(characteristic.UUID)特征发来的数据是:\(characteristic.value)=")
150
151 case "2A37":
152 println("=\(characteristic.UUID.description):\(characteristic.value)=")
153
154 case "2A38":
155 var dataValue: Int = 0
156 characteristic.value.getBytes(&dataValue, range:NSRange(location: 0, length: 1))
157 println("2A38的值为:\(dataValue)")
158
159 case "Battery Level": //如果发过来的是Byte值,在Objective-C中直接.getBytes就是Byte数组了,在swift目前就用这个方法处理吧!
160 var batteryLevel: Int = 0
161 characteristic.value.getBytes(&batteryLevel, range:NSRange(location: 0, length: 1))
162 println("当前为你检测了\(batteryLevel)秒!")
163
164 case "Manufacturer Name String": //如果发过来的是字符串,则用NSData和NSString转换函数
165 let manufacturerName: NSString = NSString(data: characteristic.value, encoding: NSUTF8StringEncoding)!
166 println("制造商名称为:\(manufacturerName)")
167
168 case "6E400003-B5A3-F393-E0A9-E50E24DCCA9E":
169 println("=\(characteristic.UUID)特征发来的数据是:\(characteristic.value)=")
170
171 case "6E400002-B5A3-F393-E0A9-E50E24DCCA9E":
172 println("返回的数据是:\(characteristic.value)")
173
174 default:
175 break
176 }
177 }
178
179 //7.这个是接收蓝牙通知,很少用。读取外设数据主要用上面那个方法didUpdateValueForCharacteristic。
180 func peripheral(peripheral: CBPeripheral!, didUpdateNotificationStateForCharacteristic characteristic: CBCharacteristic!, error: NSError!){
181 if error != nil {
182 println("更改通知状态错误:\(error.localizedDescription)")
183 }
184
185 println("收到的特性数据:\(characteristic.value)")
186 //如果它不是传输特性,退出.
187 // if characteristic.UUID.isEqual(kCharacteristicUUID) {
188 // return
189 // }
190 //开始通知
191 if characteristic.isNotifying {
192 println("开始的通知\(characteristic)")
193 peripheral.readValueForCharacteristic(characteristic)
194 }else{
195 //通知已停止
196 //所有外设断开
197 println("通知\(characteristic)已停止设备断开连接")
198 self.manager.cancelPeripheralConnection(self.peripheral)
199 }
200 }
201
202 //写入数据
203 func writeValue(serviceUUID: String, characteristicUUID: String, peripheral: CBPeripheral!, data: NSData!){
204 peripheral.writeValue(data, forCharacteristic: self.writeCharacteristic, type: CBCharacteristicWriteType.WithResponse)
205 println("手机向蓝牙发送的数据为:\(data)")
206 }
207 //用于检测中心向外设写数据是否成功
208 func peripheral(peripheral: CBPeripheral!, didWriteValueForCharacteristic characteristic: CBCharacteristic!, error: NSError!) {
209 if(error != nil){
210 println("发送数据失败!error信息:\(error)")
211 }else{
212 println("发送数据成功\(characteristic)")
213 }
214 }
215
216 func numberOfSectionsInTableView(tableView: UITableView) -> Int {
217 // #warning Potentially incomplete method implementation.
218 // Return the number of sections.
219 return 1
220 }
221
222 func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
223 // #warning Incomplete method implementation.
224 // Return the number of rows in the section.
225 return self.deviceList.count
226 }
227
228
229 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
230 //PCell,确定单元格的样式
231 let cell = tableView.dequeueReusableCellWithIdentifier("FhrCell", forIndexPath: indexPath) as! UITableViewCell
232 var device:CBPeripheral=self.deviceList.objectAtIndex(indexPath.row) as! CBPeripheral
233 //主标题
234 cell.textLabel?.text = device.name
235 //副标题
236 cell.detailTextLabel?.text = device.identifier.UUIDString
237 return cell
238 }
239
240 //通过选择来连接和断开外设
241 func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
242 if(self.peripheralList.containsObject(self.deviceList.objectAtIndex(indexPath.row))){
243 self.manager.cancelPeripheralConnection(self.deviceList.objectAtIndex(indexPath.row) as! CBPeripheral)
244 self.peripheralList.removeObject(self.deviceList.objectAtIndex(indexPath.row))
245 println("蓝牙已断开!")
246 }else{
247 self.manager.connectPeripheral(self.deviceList.objectAtIndex(indexPath.row) as! CBPeripheral, options: nil)
248 self.peripheralList.addObject(self.deviceList.objectAtIndex(indexPath.row))
249 println("蓝牙已连接! \(self.peripheralList.count)")
250 }
251 }
252
253 }
注意:
查看特性以什么方式读取,就看每个Characteristic的notifying属性值,NO说明read方式,YES说明notifying通知方式
<CBCharacteristic: 0x17008a0f0, UUID = 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0x10, value = (null), notifying = YES>
下面是properties的具体解释:
SWIFT
struct CBCharacteristicProperties : RawOptionSetType {
init(_ value: UInt)
var value: UInt
static var Broadcast: CBCharacteristicProperties { get }
static var Read: CBCharacteristicProperties { get }
static var WriteWithoutResponse: CBCharacteristicProperties { get }
static var Write: CBCharacteristicProperties { get }
static var Notify: CBCharacteristicProperties { get }
static var Indicate: CBCharacteristicProperties { get }
static var AuthenticatedSignedWrites: CBCharacteristicProperties { get }
static var ExtendedProperties: CBCharacteristicProperties { get }
static var NotifyEncryptionRequired: CBCharacteristicProperties { get }
static var IndicateEncryptionRequired: CBCharacteristicProperties { get }
}
OBJECTIVE-C
typedef enum {
CBCharacteristicPropertyBroadcast = 0x01,
CBCharacteristicPropertyRead = 0x02,
CBCharacteristicPropertyWriteWithoutResponse = 0x04,
CBCharacteristicPropertyWrite = 0x08,
CBCharacteristicPropertyNotify = 0x10,
CBCharacteristicPropertyIndicate = 0x20,
CBCharacteristicPropertyAuthenticatedSignedWrites = 0x40,
CBCharacteristicPropertyExtendedProperties = 0x80,
CBCharacteristicPropertyNotifyEncryptionRequired = 0x100,
CBCharacteristicPropertyIndicateEncryptionRequired = 0x200,
} CBCharacteristicProperties;
Swift语言iOS8的蓝牙Bluetooth解析的更多相关文章
- 基于swift语言iOS8的蓝牙连接(初步)
看过一些蓝牙App的事例,大体上对蓝牙的连接过程进行了了解.但是开始真正自己写一个小的BLE程序的时候就举步维艰了.那些模棱两可的概念在头脑中瞬间就蒸发了,所以还是决定从最基本的蓝牙连接过程进行.这里 ...
- iOS - Swift Swift 语言新特性
1.Swift 2.0 带来哪些新变化 常规变化: 1.OS X 10.11.iOS 9 和 watchOS 2 SDK 采纳了一些 Objective-C 的特性用来提高 Swift 的编程体验, ...
- Swift语言快速入门
Swift语言快速入门(首部同步新版官方API文档和语法的Swift图书,确保代码可编译,作者专家在线答疑,图书勘误实时跟进) 极客学院 编著 ISBN 978-7-121-24328-8 201 ...
- 【转】从Go、Swift语言出发
Google于2009年第一次提出了Go的构思,Facebook在去年春天引入了Hack,随后不久Apple也发布了其Swift语言. 在战争中,胜利者写历史书:在科技中,赢的公司都在写编程语言.互联 ...
- Swift语言中如何使用JSON数据教程
这是一篇翻译文章,原文出处:http://www.raywenderlich.com/82706/working-with-json-in-swift-tutorial Swift语言中如何使用JSO ...
- 总结swift语言常见的20个问题和回答
1.假设我是个刚入门的iOS开发人员,选swift学习呢,还是选objective-c学习,还是两个都学? 这个能够依据两种情况来决定:1.我想进入公司担任iOS开发的职位 2.我仅仅想做个独立 ...
- Swift语言iOS开发:CALayer十则示例
如你所知,我们在iOS应用中看到的都是视图(view),包括按钮视图.表视图.滑动条视图,还有可以容纳其他视图的父视图等. AD:[活动]Web和APP兼容性实战 Win10训练营免费报名 如你所知, ...
- android -- 蓝牙 bluetooth (三)搜索蓝牙
接上篇打开蓝牙继续,来一起看下蓝牙搜索的流程,触发蓝牙搜索的条件形式上有两种,一是在蓝牙设置界面开启蓝牙会直接开始搜索,另一个是先打开蓝牙开关在进入蓝牙设置界面也会触发搜索,也可能还有其它触发方式,但 ...
- 学习swift语言的快速入门教程推荐
随着苹果产品越来越火爆,苹果新推出的swift必定将在很大程度上代替oc语言.学好swift语言,对于IOS工程师来讲,已经是一门必备技能. 有一些比较好的英文版教程,值得学习. 1. Swift T ...
随机推荐
- python map, reduce,filter 使用
参考python built-on function: http://docs.python.org/2.7/library/functions.html?highlight=map%20reduce ...
- ios 开发 常见问题解决 (持续更新)
1.使用cocoaPods引用第三方类库,报错:file not found . 解决方案:设置 Project->Info->Configurations之后 clear ,然后再 ...
- android listview 三种适配器设置
1: public class ArrayAdapterActivity extends ListActivity { @Override public void onCreate(Bundle sa ...
- 网站制作---eWebeditor不兼容IE8问题的解决方法
qq交流群:创梦技术交流群:251572072 创梦网络赚钱群:248318056 创梦娱乐休闲群:22 ...
- 如何修改 UINavigationController、UINavigationBar 中 navigationItem 左侧 “返回” 按钮的名称
如果我们从 title 为 “首页” 的页面 A 点击进入一个子页面 B,那么在页面 B 的左上角将显示一个名为 “<首页” 的按钮.假设这个页面 A 叫 “你是我天边最美的云彩”,那在页面 B ...
- oracle&&Sqlserver获取表名列名主键及数据类型
SQlserver获得列名,列类型,列类型长度,scale,prec等数据类型(syscolumns,systypes,sysobjects均为视图) select a.name as colname ...
- C#小性能知识
字符串比较 string s = ""; 1) if(s == ""){} 2) if(s == string.Empty){} 3) if (string.I ...
- 根据自己的需要适度使用Web开发框架
软件系统发展到今天已经很复杂了,特别是服务器端软件,涉及到的知识,内容,问题太多.Web开发框架能够帮我们大大减少工作量,但是我们应该如何正确看待Web开发框架,并且如何去使用他们呢? 对框架的依赖 ...
- send js object to webapi or mvc
[HttpPost] public HttpResponseMessage AddInfo(UserInfoEntity userInfo) { return Request.CreateRespon ...
- Oracle EBS Concurrent Request:Gather Schema Statistics[Z]
Oracle EBS 的Concurrent Request"Gather Schema Statistics"是一个和性能相关的Concurrent Program,它会对表,列 ...