您的位置:首页 > 移动开发 > Swift

iOS 蓝牙使用小结 bluetooth中心模式swift,oc

2017-01-01 14:36 393 查看
demo下载 http://download.csdn.NET/detail/swibyn/9717588

直接看代码 http://blog.csdn.Net/swibyn/article/details/53785249

首先推荐去看官方文档哦

现将创建蓝牙工程的要点总结一下,由于工程主要涉及中心模式,所以只总结中心模式的用法

1,引入CoreBluetooth.framework

2,实现蓝牙协议,如:

.h文件如下

@protocolCBCentralManagerDelegate;

@protocolCBPeripheralDelegate;

@interface ViewController :UIViewController<CBCentralManagerDelegate,CBPeripheralDelegate>

.m文件如下

#import "CoreBluetooth/CoreBluetooth.h"

另外还有代理部分请自行添加

3,下面是使蓝牙动起来的过程

3.1创建CBCentralManager实例

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

设置代理,比如:

    self.cbCentralMgr.delegate =self;

创建数组管理外设

    self.peripheralArray = [NSMutableArrayarray];

3.2扫描周围的蓝牙

实际上周围的蓝牙如果可被发现,则会一直往外发送广告消息,中心设备就是通过接收这些消息来发现周围的蓝牙的

    [self.cbCentralMgr scanForPeripheralsWithServices:nil options:nil];

3.3发现一个蓝牙设备

也就是收到了一个周围的蓝牙发来的广告信息,这是CBCentralManager会通知代理来处理

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

{

}

如果周围的蓝牙有多个,则这个方法会被调用多次,你可以通过tableView或其他的控件把这些周围的蓝牙的信息打印出来

3.4连接一个蓝牙

[self.cbCentralMgrconnectPeripheral:peripheral options:nil];

一个中心设备可以同时连接多个周围的蓝牙设备

当连接上某个蓝牙之后,CBCentralManager会通知代理处理

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

{

}

因为在后面我们要从外设蓝牙那边再获取一些信息,并与之通讯,这些过程会有一些事件可能要处理,所以要给这个外设设置代理,比如:

peripheral.delegate =self;

3.5查询蓝牙服务

[peripheral discoverServices:nil];

返回的蓝牙服务通知通过代理实现

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

{

   for (CBService* service in peripheral.services){

        

    }

}

3.6查询服务所带的特征值

[peripheral discoverCharacteristics:nil forService:service];

返回的蓝牙特征值通知通过代理实现

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

{

    

   for (CBCharacteristic * characteristic in service.characteristics) {

    }

1cca8
}

3.7给蓝牙发数据

[peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];

这时还会触发一个代理事件

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

{

}

3.8处理蓝牙发过来的数据

一种方法是主动读取数据,不过更好的办法是设置事件通知。

[peripheral setNotifyValue:YES forCharacteristic:characteristic];

这样当有数据时会自动触发代理事件

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

{

}

3.9 retrievePeripheralsWithIdentifiers使用例子

-(IBAction) Retrieve:(id)Sender

{

    [self.tvLogsetText:@""];

    NSMutableArray * Identifiers = [NSMutableArrayarray];

   for (CBPeripheral * peripheralinself.peripheralArray)
{

        [IdentifiersaddObject:peripheral.identifier];

    }

    [selfaddLog:@"[self.cbCentralMgr retrievePeripheralsWithIdentifiers:self.PeripheralIdentifiers]"];

    self.retrievePeripherals = [self.cbCentralMgrretrievePeripheralsWithIdentifiers:Identifiers];

   for (CBPeripheral* peripheralinself.retrievePeripherals)
{

        [selfaddLog:[NSStringstringWithFormat:@"%@ name:%@",peripheral,peripheral.name]];

    }

    [self.tableViewPeripheralreloadData];

}

3.10 retrieveConnectedPeripheralsWithServices使用例子

-(IBAction) Retrieve:(id)Sender

{

    [self.tvLogsetText:@""];

    NSMutableArray * services = [NSMutableArrayarray];

   for (CBPeripheral * peripheralinself.peripheralArray)
{

       if (peripheral.isConnected) {

           for (CBService *servicein peripheral.services) {

                [servicesaddObject:service.UUID];

            }

        }

    }

    

    [selfaddLog:@"[self.cbCentralMgr retrieveConnectedPeripheralsWithServices:peripheral.services]"];

    self.retrievePeripherals = [self.cbCentralMgrretrieveConnectedPeripheralsWithServices:services];

   for (CBPeripheral* peripheralinself.retrievePeripherals)
{

        [selfaddLog:[NSStringstringWithFormat:@"%@ name:%@",peripheral,peripheral.name]];

    }

    [self.tableViewPeripheralreloadData];

}

大概就这个个流程,例子中的参数设置,及其其他的一些代理请自己研究。

import UIKit

import CoreBluetooth

/**

 中心管理模式

 1.引入CoreBluetooth,初始化中心管理者

 2.监听cMgr的状态,当是On的时候,才可以进行搜索外设

 3.当状态为On的时候,开始搜索我们的外设

 4.发现外设后,过滤出我们要的外设,并且对其进行标记或者存储到外设数组中(每个中心管理者都可以连接1-7个外设,但是每个外设都只能连接一个cMgr)

 */

class ViewController: UIViewController {

    var cMgr :CBCentralManager!

    var per:
CBPeripheral?

    //var start :Bool?

    

    @IBAction
func startBLE() {

        //self.start = true

        // 1.初始化中心管理者

        self.cMgr =
CBCentralManager(delegate:
self, queue: dispatch_get_main_queue(), options:
nil)

    }

   

    @IBAction
func stopConnect() {

        //self.start = false

        self.yf_cMgr(self.cMgr,
stopConnectWithPeripheral: self.per!)

    }

    override
func viewDidLoad() {

        super.viewDidLoad()

        // Do any additional setup after loading the view, typically from a nib.

        

    }

}

extension ViewController:
CBCentralManagerDelegate

{

    // 2.监听cMgr的状态(模拟器永远不会是On)

    func centralManagerDidUpdateState(central:
CBCentralManager) {

        //

        switch central.state {

        case .PoweredOff:

            print("PoweredOff")

        case .PoweredOn:

            print("PoweredOn")

            // 3.搜索外设.会触发 centralManager:didDiscoverPeripheral:advertisementData:RSSI:

            central.scanForPeripheralsWithServices(nil, options:
nil)

        case .Resetting:

            print("Resetting")

        case .Unsupported:

            // 使用模拟器会打印此处

            print("Unsupported")

        default:

            print("others")

        }

    }

    

    // 4.发现外设

    func centralManager(central:
CBCentralManager, didDiscoverPeripheral peripheral:
CBPeripheral, advertisementData: [String :
AnyObject], RSSI:
NSNumber) {

        print("central:
\(central), peripheral:
\(peripheral), adv:
\(advertisementData), RSSI:
\(RSSI)")

        

        // 一般会根据advertisementData来过滤出我们想要连接的外设(当然,信号强度RSSI也可以作为过滤凭据)

        /**

         ["kCBAdvDataManufacturerData": <570100ae fcda4d72 8ea10132 3c4dafc4 22aec402 880f1060 8b1d>, "kCBAdvDataIsConnectable": 1, "kCBAdvDataServiceUUIDs": <__NSArrayM 0x1545560e0>(

         FEE0,

         FEE7

         )

         , "kCBAdvDataServiceData": {

         FEE0 = <54080000>;

         }, "kCBAdvDataLocalName": MI]

         */

        let advRecName = advertisementData[CBAdvertisementDataLocalNameKey]
as? String

        if (advRecName!.containsString("MI"))

        {

            print("advRecName:
\(advRecName) success")

            // 5.连接想要的外设

            // 5.1.停止扫描

            central.stopScan()

            //self.start = false

            // 5.2.将外设标记/存入外设数组(1-7)(1-1)

            self.per = peripheral

            // 5.3.连接这个外设

            central.connectPeripheral(self.per!, options:
nil)

            

        }else

        {

            print(advRecName)

        }

    }

    

    // 6.连接外设的结果

    // 6.1 连接成功

    func centralManager(central:
CBCentralManager, didConnectPeripheral peripheral:
CBPeripheral) {

        //

        print("didConnectPeripheral")

        peripheral.delegate =
self

        // 7. 与外设信息进行分析交互

        peripheral.discoverServices(nil)

    }

    

    // 6.2 连接失败

    func centralManager(central:
CBCentralManager, didFailToConnectPeripheral peripheral:
CBPeripheral, error:
NSError?) {

        print("didFailToConnectPeripheral")

    }

    

   
// 6.3 丢失连接(手动取消调用/
每信号了也调用)

    func centralManager(central:
CBCentralManager, didDisconnectPeripheral peripheral:
CBPeripheral, error:
NSError?) {

        //

        print("didDisconnectPeripheral")

    }

    

   
// 自定义的取消连接方法

    func yf_cMgr(central:
CBCentralManager,stopConnectWithPeripheral peripheral:
CBPeripheral) -> ()

    {

        central.stopScan()

        central.cancelPeripheralConnection(peripheral)

    }

}

extension ViewController:
CBPeripheralDelegate

{

    // 7.1 外设发现服务

    func peripheral(peripheral:
CBPeripheral, didDiscoverServices error:
NSError?) {

        guard error ==
nil else

        {

            print("didDiscoverServices :
\(error)")

            return

        }

        

        for service
in peripheral.services! {

            // 7.2 外设检索服务中的每一个特征 peripheral:didDiscoverCharacteristicsForService

            peripheral.discoverCharacteristics(nil, forService: service)

        }

    }

    

    // 7.3 外设发现服务中的特征

    func peripheral(peripheral:
CBPeripheral, didDiscoverCharacteristicsForService service:
CBService, error:
NSError?) {

        guard error ==
nil else

        {

            print("didDiscoverCharacteristicsForService :
\(error)")

            return

        }

        

        print(service.characteristics!.count)

        for character
in service.characteristics! {

            // 7.4 外设检索特征的描述  peripheral:didDiscoverDescriptorsForCharacteristic:error:

            peripheral.discoverDescriptorsForCharacteristic(character)

            

            // 判断如果特征的UUID是 2B4A,那就对其进行订阅

            if character.UUID.isEqual(CBUUID(string:
"2B4A"))

            {

                self.yf_Per(peripheral, setNotifyValueForCharacteristic: character)

            }

            

            // 7.5 外设读取特征的值

            guard character.properties.contains(.Read)
else

            {

                print("character.properties must contains read")

               
// 如果是只读的特征,那就跳过本条进行下一个遍历

                continue

            }

            print("note guard")

            // peripheral:didUpdateValueForCharacteristic:error:

            peripheral.readValueForCharacteristic(character)

        }

    }

    

    // 7.6 外设发现了特征中的描述

    func peripheral(peripheral:
CBPeripheral, didDiscoverDescriptorsForCharacteristic characteristic:
CBCharacteristic, error:
NSError?) {

        //

        guard error ==
nil else

        {

            print("didDiscoverDescriptorsForCharacteristic :
\(error)")

            return

        }

        

        for des
in characteristic.descriptors! {

            print("characteristic:
\(characteristic) .des  :\(des)")

            // peripheral:didUpdateValueForDescriptor:error: method

            peripheral.readValueForDescriptor(des)

        }

    }

    

    // 7.7 更新特征value

    func peripheral(peripheral:
CBPeripheral, didUpdateValueForCharacteristic characteristic:
CBCharacteristic, error:
NSError?) {

        guard error ==
nil else

        {

            print("didUpdateValueForCharacteristic :
\(error)")

            return

        }

        

        print("\(characteristic.description)
didUpdateValueForCharacteristic")

    }

    

    func yfPer(peripheral:
CBPeripheral, writeData data:
NSData, forCharacteristic characteristic:
CBCharacteristic) -> () {

        //外设写输入进特征

        guard characteristic.properties.contains(.Write)
else

        {

            print("characteristic.properties must contains Write")

            return

        }

        // 会触发peripheral:didWriteValueForCharacteristic:error:

        peripheral.writeValue(data, forCharacteristic: characteristic, type:
CBCharacteristicWriteType.WithResponse)

    }

    // 订阅与取消订阅

    func yf_Per(peripheral:
CBPeripheral, setNotifyValueForCharacteristic characteristic:
CBCharacteristic) -> () {

        guard characteristic.properties.contains(.Notify)
else

        {

            print("characteristic.properties must contains notify")

            return

        }

        // peripheral:didUpdateNotificationStateForCharacteristic:error:

        peripheral.setNotifyValue(true, forCharacteristic: characteristic)

    }

    func yf_Per(peripheral:
CBPeripheral, canleNotifyValueForCharacteristic characteristic:
CBCharacteristic) -> () {

        guard characteristic.properties.contains(.Notify)
else

        {

            print("characteristic.properties must contains notify")

            return

        }

        peripheral.setNotifyValue(false, forCharacteristic: characteristic)

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: