ios蓝牙开发学习笔记(二)central角色的实现

本文转载自:http://blog.csdn.net/swibyn/article/details/52096321

Performing Common Central Role Tasks

central角色的实现

central 角色需要完成的几件事情,如搜索,连接,与peripheral交互数据。
peripheral 角色同样需要完成几件事情,如,发布和广播服务,响应读,写,订阅请求

本章中,你将学习如何完成central端的功能。
1,创建central manager 对象
2,发现和连接正在广播的peripheral
3,浏览peripheral的数据
4,发送读和写请求到peripheral设备
5,订阅characteristic的值

下一章你将学习如何开发peripheral角色的功能

Starting Up a Central Manager

创建Central manager对象

myCentralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:nil];'

在这里self设置成central角色的代理。dispath queue设置为nil,意味着central事件将交由main queue处理。

创建central manager时,会触发centralManagerDidUpdateState: 代理方法。你必须实现这个代理。

Discovering Peripheral Devices That Are Advertising

搜索正在发送广播的peripheral

[myCentralManager scanForPeripheralsWithServices:nil options:nil];

注意:如果第一个参数设置成nil,那么centralmanager会返回所有被发现的peripherals,在实际应用中,你应该给他赋值 CBUUID 对象数组。这样只有有广播这些uuid服务的peripheral才会被返回,

一旦发现peripheral,将触发
centralManager:didDiscoverPeripheral:advertisementData:RSSi:
代理方法,如果你想连接这个peripheral,请使用强引用变量引用它,这样系统就不会释放掉它。

  • (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral
    advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
    NSLog(@"Discovered %@", peripheral.name);
    self.discoveredPeripheral = peripheral;
    ...

如果你想连接多个设备,你可以使用NSArray来管理他们。不管什么情况,一旦你找到所有你想要的设备,你应该停止扫描以便节省电量。

[myCentralManager stopScan];

Connecting to a Peripheral Device After You’ve Discovered It

连接peripheral

[myCentralManager connectPeripheral:peripheral options:nil];

如果连接成功,则会触发centralManager:didConnectPeripheral:代理方法,与之通讯之前,你需要为它设置代理

  • (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
    NSLog(@"Peripheral connected");
    peripheral.delegate = self;
    ...

Discovering the Services of a Peripheral That You’re Connected To

查询peripheral的服务

建立连接之后,就可以查询数据,第一步就是查询有哪些services。因为广播包有大小限制,在广播中可能没有显示全部的服务信息,这里你可以使用discoverServices: 来查询所有的services。

[peripheral discoverServices:nil];

注意:实际开发中,你不应该传值nil,因为这样做会返回所有的services,包括那些你不需要的services,这样做会浪费时间和电量。所以你应该传递你需要的uuids。

查找到所有的服务会触发peripheral:didDiscoverServices:代理方法

  • (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
    for (CBService *service in peripheral.services) {
    NSLog(@"Discovered service %@", service);
    ...
    }
    ...

Discovering the Characteristics of a Service

查找characteristics

发现service之后,下一步就是查找characteristics

NSLog(@"Discovering characteristics for service %@", interestingService);
[peripheral discoverCharacteristics:nil forService:interestingService];

注意:实际开发中,不要传nil,这样做会返回所有的characteristics,包括那些你不感兴趣的characteristics。这样做即浪费时间又损耗电量。所以你应该传你需要的uuids的值

查找到characteristics之后,会触发peripheral:didDiscoverCharacteristicsForService:error:代理方法

  • (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
    for (CBCharacteristic *characteristic in service.characteristics) {
    NSLog(@"Discovered characteristic %@", characteristic);
    ...
    }
    ...

Retrieving the Value of a Characteristic

获取数据

一个characteristic只包含一种信息数据。比如恒温service下的温度characteristic只包含当前温度值,你可以通过读取或订阅来获得这个值。

Reading the Value of a Characteristic

读取characteristic的数据

NSLog(@"Reading value for characteristic %@", interestingCharacteristic);
[peripheral readValueForCharacteristic:interestingCharacteristic];

获取到数据后peripheral调用peripheral:didUpdateValueForCharacteristic:error:代理方法

  • (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    NSData *data = characteristic.value;
    // parse the data as needed
... 

注意:并不是所有的characteristic都是可读的,你可以通过 characteristic的 proterties属性是否包含CBCharacteristicPropertyRead 常量来判断是否可读。在读一个不可读的characteristic的数据值,会在代理方法的error参数中体现异常信息

Subscribing to a Characteristic’s Value

订阅characteristic的值

虽然通过readValueForCharacteristic: 可以有效获取静态值,但如果值是动态改变的,则最好使用订阅的方法。当值变化时,自动获得通知。
设置订阅

[peripheral setNotifyValue:YES forCharacteristic:interestingCharacteristic];

订阅的时候peripheral会调用peripheral:didUpdateNotificationStateForCharacteristic:error: 代理方法。如果订阅失败了,也可以通过这个方法查询失败的原因

  • (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    if (error) {
    NSLog(@"Error changing notification state: %@",[error localizedDescription]);
    }

注意:并不是所有的characteristics都可以订阅,可以通过检查characteristic的properties属性是否包含CBCharacteristicPropertyNotify 或 CBCharacteristicPropertyIndicate常量来判断是否可订阅

Writing the Value of a Characteristic

写数据

有时也是需要写数据的,比如恒温器,你需要设置目标温度。如果characteristic是可写的,那么你就可以调用writeValue:forCharacteristic:type: 方法来写入数据。如下:

NSLog(@"Writing value for characteristic %@", interestingCharacteristic);
[peripheral writeValue:dataToWrite forCharacteristic:interestingCharacteristic type:CBCharacteristicWriteWithResponse];

当你写数据时,你可以标明写类型。上例中,写类型是CBCharacteristicWriteWithResponse, 这种情况下,不管有没有写成功,peripheral都会通过代理通知你。你需要实现这个方法以便处理异常情况。

  • (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    if (error) {
    NSLog(@"Error writing characteristic value: %@",[error localizedDescription]);
    }
    ...

如果你设置的写类型是CBCharacteristicWriteWithoutResponse, 那么写操作会以更有效的方式执行,但不保证写成功,并且不会有报告。peripheral不会通知任何回调。

注意:characteristic可能只支持特定的写类型,或不支持写操作。你可以通过检查properties属性是否包含CBCharacteristicPropertyWriteWithoutResponse 或 CBCharacteristicPropertyWrite 来判断。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容