☻蓝牙(BLE4.0)

开发中央步骤:

  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;

 

你可能感兴趣的:(B)