最近这段时间在研究蓝牙,也研究了一段时间了现在在下面做个总结

1 其实蓝牙连接只要明白了整体原理,其实挺简单的 

2 大部分情况下,手机作为中心管理者,而连接的设备被称为外设,外设的结构有点像一颗大树,外设我把它看成是大叔的树干,然后由树干向上生成生成许多树干分支,这些分支就是服务,分支上面在分的小分支就是特征,而小树枝上面的职业可以看成是特征的描述。

3 然后就需要知道哪根树枝为你服务了,苹果取名字为服务,那就是为你服务的,所以你需要知道是哪跟树枝为你服务

知道了哪根树枝之后就需要分析这根树枝上的小枝干到底是是些什么功能,其实这些小枝干就是所谓的"特征" 

然后根据硬件工程师提供的UUID 记录下可以读取信息的特征,对这个特征监听它的值的变化。

4 同样的根据硬件工程师提供的UUID 记录下可以写入信息额特征,方便后期对特征进行数据命令写入来操作蓝牙设备。蓝牙大体就这样一个流程了,下面说下代码如何一步一步实现上述过程

1. 首先是想要导入蓝牙需要的头文件  CoreBluetooth

然后实例化中心管理者

self.manger=[[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_main_queue()];

中心管理者实例化了会自动触发监测蓝牙状态的代理

/*
CBManagerStateUnknown = 0,
CBManagerStateResetting,
CBManagerStateUnsupported,
CBManagerStateUnauthorized,
CBManagerStatePoweredOff,
CBManagerStatePoweredOn,
监测蓝牙状态
*/
-(void)centralManagerDidUpdateState:(CBCentralManager *)central{
switch (central.state) {
case CBManagerStatePoweredOn:
{
NSLog(@"蓝牙已开启");
[self.manger scanForPeripheralsWithServices:nil options:nil];
}
break;
case CBManagerStatePoweredOff:{ }
break;
default:
break;
}
}

在蓝牙开启的情况下去扫描周围的蓝牙设备 然后扫描到了设备会调用到下面的方法

#pragma mark  扫描 发现周围设备
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI{
NSLog(@"%@===%ld",peripheral.name,(long)peripheral.state);
//发现需要的设备 进行蓝牙连接
if ([peripheral.name rangeOfString:@"BP826"].length!=) {
self.pheral=peripheral;
[self.manger connectPeripheral:peripheral options:nil];
[central stopScan];
} }

找到对应的蓝牙设备进行蓝牙连接 成功、失败、断开连接会有下面回调

#pragma mark  连接成功对应设备
-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
// self.pheral=peripheral;
peripheral.delegate=self; [peripheral discoverServices:nil]; NSLog(@"连接上了对应的设备");
}
#pragma mark 断开连接
-(void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{ }
#pragma mark 连接失败 失败
-(void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{ }

成功连接上外设之后就是去发现外设里面的服务    [peripheral discoverServices:nil];

然后发现服务会调用下面的方法 找到你需要的那个服务,然后再去发现你的那个服务中的特征

#pragma mark  发现服务
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
for (CBService *service in peripheral.services) {
if ([service.UUID.UUIDString isEqualToString:kSERVICEUUID]) {
[peripheral discoverCharacteristics:nil forService:service];
}
}
}

然后就回去寻找服务中的特征 然后根据硬件提供给你的读取或者写入的特征ID去找到对应的特征 然后记录下来

并对读取的特征进行特征值变化的监听

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(nullable NSError *)error{
for (CBCharacteristic *character in service.characteristics) {
if ([character.UUID.UUIDString isEqualToString:kread_UUID]) {
self.readCharacter=character;
//开启特征值变化监听 值变化了会调用 peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
[peripheral setNotifyValue:YES forCharacteristic:character];
}
if ([character.UUID.UUIDString isEqualToString:kwrite_UUID]) {
self.writeCharater=character;
}
}
}

然后特征值发生变化了会调用到下面的方法

#pragma mark  特征值发生变化
-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
NSLog(@"%@",characteristic.value);
}

如果你想对硬件操作  那么你需要给写入的那个特征写入值  需要调用

[self.pheral writeValue:[self convertHexStrToData:@"A0A0A0A0A0A0A0"]  forCharacteristic:self.writeCharater type:CBCharacteristicWriteWithResponse];

//字符串命令装换成NSData类型
- (NSData *)convertHexStrToData:(NSString *)str {
if (!str || [str length] == ) {
return nil;
} NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:];
NSRange range;
if ([str length] % == ) {
range = NSMakeRange(, );
} else {
range = NSMakeRange(, );
}
for (NSInteger i = range.location; i < [str length]; i += ) {
unsigned int anInt;
NSString *hexCharStr = [str substringWithRange:range];
NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr]; [scanner scanHexInt:&anInt];
NSData *entity = [[NSData alloc] initWithBytes:&anInt length:];
[hexData appendData:entity]; range.location += range.length;
range.length = ;
}
return hexData;
}

到此为止整个蓝牙设备基础的功能就列举完了 这也是自己这段时间研究小小的成果吧  fighting!

ios蓝牙详解的更多相关文章

  1. 【转】IOS AutoLayout详解(三)用代码实现(附Demo下载)

    转载自:blog.csdn.net/hello_hwc IOS SDK详解 前言: 在开发的过程中,有时候创建View没办法通过Storyboard来进行,又需要AutoLayout,这时候用代码创建 ...

  2. IOS SDK详解

    来源:http://blog.csdn.net/column/details/huangwenchen-ios-sdk.html?page=1#42803301 博客专栏>移动开发专栏>I ...

  3. iOS路由详解

    本文如题,路由详解,注定是一篇详细解释iOS路由原理及使用的文章,由于此时正在外地出差,无法详细一一写出,只能不定时的补充. 一.什么是iOS路由 路由一词来源于路由器,可以实现层级之间消息转发的功能 ...

  4. IOS 手势详解

    在IOS中手势可以让用户有很好的体验,因此我们有必要去了解一下手势. (在设置手势是有很多值得注意的地方) *是需要设置为Yes的点击无法响应* *要把手势添加到所需点击的View,否则无法响应* 手 ...

  5. IOS SizeClasses 详解

    SizeClasses 详解 iOS 8在应用界面的可视化设计上添加了一个新的特性-Size Classes.对于任何设备来说,界面的宽度和高度都只分为三种描述:紧凑,任意和宽松.这样开发者便可以无视 ...

  6. iOS模式详解—「runtime面试、工作」看我就 🐒 了 ^_^.

    Write in the first[写在最前] 对于从事 iOS 开发人员来说,当提到 ** runtime时,我想都可以说出来 「runtime 运行时」和基本使用的方法.相信很多开发者跟我当初一 ...

  7. iOS 模式详解—「runtime面试、工作」看我就 🐒 了 ^_^.

    引导 Copyright © PBwaterln Unauthorized shall not be *copy reprinted* . 对于从事 iOS 开发人员来说,所有的人都会答出「runti ...

  8. ios学习--详解IPhone动画效果类型及实现方法

    详解IPhone动画效果类型及实现方法是本文要介绍的内容,主要介绍了iphone中动画的实现方法,不多说,我们一起来看内容. 实现iphone漂亮的动画效果主要有两种方法,一种是UIView层面的,一 ...

  9. iOS中 蓝牙2.0详解/ios蓝牙设备详解 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博 整体布局如下:     程序结构如右图: 每日更新关注:http://weibo.com/hanjunqiang  ...

随机推荐

  1. postfix 指定用户限制指定域名收发

    main.cf 配置示例: smtpd_restriction_classes = local_in_only, local_out_only local_in_only = check_recipi ...

  2. 第25月第5天 Hands-on Machine Learning with Scikit-Learn and TensorFlow

    1.apachecn视频(机器学习实战) https://github.com/apachecn/AiLearning https://space.bilibili.com/97678687/#/ch ...

  3. C++11 线程并发

    并发 头文件<future> <thread> 高级接口 async().future<> future<int> result1; //int为fun ...

  4. js2wordcloud 词云包的使用

    js文件下载: https://github.com/liangbizhi/js2wordcloud/tree/master/ dist文件夹内 引用: <script src="** ...

  5. 【mmall】递归查询子节点并排重

    代码 @Override public ServerResponse getSelfAndChildrenCategory(Integer categoryId) { if (categoryId ! ...

  6. drozer的使用介绍

    0x00. 配置adb环境变量 下载地址:http://pan.baidu.com/s/1o8itZtC 密码:9o6j 如何配置android的adb环境变量 http://jingyan.baid ...

  7. layer兼容性问题

    一.Layer 弹出层在ie8错乱的解决办法 弹出层在火狐.谷歌.360极速模式.IE6下都能100%面积正常显示,但在IE8和360的兼容模式下只显示弹出层下半部分或右半部分的内容,在主页面加上: ...

  8. redis-LinkedList

    1.redis-LinkedList[重点] Java List :  数组ArrayList 链表LinkedList 为什么redis选取了链表? Redis操作中,最多的操作是进行元素的增删 使 ...

  9. 20165237 2017-2018-2 《Java程序设计》第8周学习总结

    20165237 2017-2018-2 <Java程序设计>第8周学习总结 教材学习内容总结 1.程序:一段静态的代码,它是应用软件执行的蓝本. 2.进程:程序的一次动态执行过程,它对应 ...

  10. centos设置服务开机启动失败问题

    1.安装某服务设置开机启动的时候报错 [root@node1 ~]# systemctl enable lvm2-lvmetad.serviceThe unit files have no [Inst ...