iOS蓝牙--CoreBluetooth基本使用
蓝牙使用步骤:
1. 扫描外设
2. 连接外设
3. 连上外设后,获取指定外设的服务
4. 获取服务后,遍历服务的特征,得到可读,可写等特征,然后与中心管理者进行数据交互
附上代码
一:导入框架
#import <CoreBluetooth/CoreBluetooth.h>
#import <CoreLocation/CoreLocation.h>
二:设置代理,以及属性
<CBCentralManagerDelegate, CBPeripheralDelegate, UITableViewDataSource, UITableViewDelegate,CLLocationManagerDelegate>
/**
* 外设数组
*/
@property (nonatomic, strong) NSMutableArray *peripherals;
/**
* 中心管理者
*/
@property (nonatomic, strong) CBCentralManager *mgr;
/*
* 展示数据
*/
@property (nonatomic, strong) UITableView *tableView;
// 外设
@property (nonatomic, strong) CBPeripheral *peripheral;
// 特征
@property (nonatomic, strong) CBCharacteristic *characteristic;
三:方法实现
//懒加载 重写getter方法
- (NSMutableArray *)peripherals
{
if (!_peripherals) {
_peripherals = [NSMutableArray array];
}
return _peripherals;
}
- (void)viewDidLoad
{
[super viewDidLoad];
UIBarButtonItem *buttonI = [[UIBarButtonItem alloc] initWithTitle:@"扫描" style:UIBarButtonItemStylePlain target:self action:@selector(openOrclosed)];
self.navigationItem.rightBarButtonItem = buttonI;
UIBarButtonItem *buttonRB = [[UIBarButtonItem alloc] initWithTitle:@"open" style:UIBarButtonItemStylePlain target:self action:@selector(openTheDoor)];
self.navigationItem.leftBarButtonItem = buttonRB;
self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.height) style:UITableViewStylePlain];
[self.view addSubview:self.tableView];
self.tableView.delegate = self;
self.tableView.dataSource = self;
// Do any additional setup after loading the view.
}
#pragma mark - CBCentralManagerDelegate
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
// 保存扫描到得外部设备
// 判断如果数组中不包含当前扫描到得外部设置才保存
NSLog(@"查找设备");
if (![self.peripherals containsObject:peripheral]) {
// if ([peripheral.identifier.UUIDString isEqualToString:@""]) {
[self.peripherals addObject:peripheral];
// peripheral.delegate = self;
[self.tableView reloadData];
// }
}
}
#pragma mark 显示数据的tableView的代理方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.peripherals.count;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cell_id = @"cell_id";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cell_id];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cell_id];
}
CBPeripheral *peripheral = self.peripherals[indexPath.row];
cell.textLabel.text = peripheral.name;
return cell;
}
#pragma mark tableView的点击事件
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// self.peripheral = self.peripherals[indexPath.row];
// self.peripheral.delegate = self;
// ((CBPeripheral *)self.peripherals[indexPath.row]).delegate=self;
// [self.mgr connectPeripheral:self.peripherals[indexPath.row] options:nil];
self.peripheral = self.peripherals[indexPath.row];
[self.mgr connectPeripheral:self.peripheral options:nil];
self.peripheral.delegate = self;
// ((CBPeripheral *)self.peripherals[indexPath.row]).delegate=self;
}
/**
* 扫描外设
*/
- (void)openOrclosed
{
if ([self.navigationItem.rightBarButtonItem.title isEqualToString:@"扫描"]) {
NSLog(@"扫描");
[self.navigationItem.rightBarButtonItem setTitle:@"断开"];
// 1.创建中心设备
// 设置代理
self.mgr = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
// 2.利用中心设备扫描外部设备
/*
如果指定数组代表只扫描指定的设备
*/
[self.mgr scanForPeripheralsWithServices:nil options:nil];
} else {
NSLog(@"断开");
[self.mgr stopScan];
if (self.peripheral != nil)
{
NSLog(@"disConnect start");
[self.mgr cancelPeripheralConnection:self.peripheral];
}
self.peripherals = nil;
[self.tableView reloadData];
[self.navigationItem.rightBarButtonItem setTitle:@"扫描"];
}
}
/**
* 连接外设成功调用
*/
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
// [self showTheAlertViewWithMassage:@"链接成功"];
NSLog(@"链接成功");
// 扫描外设中得服务
[peripheral discoverServices:nil];
}
/**
* 连接外设失败调用
*/
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
// [self showTheAlertViewWithMassage:@"链接失败"];
NSLog(@"链接失败");
}
#pragma makr - CBPeripheralDelegate
/**
* 只要扫描到服务就会调用
*
* @param peripheral 服务所在的外设
*/
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
NSLog(@"扫描服务");
// [self showTheAlertViewWithMassage:@"扫描服务"];
// 获取外设中所有扫描到得服务
NSArray *services = peripheral.services;
for (CBService *service in services) {
// 拿到需要的服务
NSLog(@"%@", service.UUID.UUIDString);
if ([service.UUID.UUIDString isEqualToString:RX_SERVICE_UUID])
{
[self showTheAlertViewWithMassage:@"拿到了对应的服务了"];
// 从需要的服务中查找需要的特征
// 从peripheral中得service中扫描特征
[peripheral discoverCharacteristics:nil forService:service];
}
}
}
/**
* 只要扫描到特征就会调用
*
* @param peripheral 特征所属的外设
* @param service 特征所属的服务
*/
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
NSLog(@"扫描特征");
// 拿到服务中所有的特征
NSArray *characteristics = service.characteristics;
// 遍历特征, 拿到需要的特征处理
for (CBCharacteristic * characteristic in characteristics) {
if ([characteristic.UUID.UUIDString isEqualToString:RX_CHAR_UUID]) {
// [self showTheAlertViewWithMassage:@"拿到只读的的特征了"];
NSLog(@"拿到可写的的特征了");
// characteristic.value
NSString *valueStr = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding];
NSLog(@"%@????", valueStr);
self.characteristic = characteristic;
[self showTheAlertViewWithMassage:valueStr];
}
if ([characteristic.UUID.UUIDString isEqualToString:TX_CHAR_UUID]) {
}
}
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
NSLog(@"检测代理方法");
if (central.state == 5) {
[self.mgr scanForPeripheralsWithServices:nil options:nil];
// [self showTheAlertViewWithMassage:@"手机蓝牙处于可用状态"];
}
NSLog(@"%ld, %@", central.state, central);
}
#pragma mark 发送消息成功
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
NSLog(@"发送消息的回调");
NSLog(@"----%@", error);
if (!error) {
NSLog(@"??????????");
}
}
#pragma mark 处理蓝牙发送过来的数据
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForDescriptor:(CBDescriptor *)descriptor error:(NSError *)error
{
NSLog(@"接收到数据");
}
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
NSLog(@">>>>>>>");
if (error)
{
NSLog(@"Error updating value for characteristic %@ error: %@", characteristic.UUID, [error localizedDescription]);
// if ([_mainMenuDelegate respondsToSelector:@selector(DidNotifyReadError:)])
// [_mainMenuDelegate DidNotifyReadError:error];
//
// return;
}
NSMutableData *recvData;
[recvData appendData:characteristic.value];
if ([recvData length] >= 5)//已收到长度
{
unsigned char *buffer = (unsigned char *)[recvData bytes];
int nLen = buffer[3]*256 + buffer[4];
if ([recvData length] == (nLen+3+2+2))
{
//接收完毕,通知代理做事
// if ([_mainMenuDelegate respondsToSelector:@selector(DidNotifyReadData)])
// [_mainMenuDelegate DidNotifyReadData];
NSLog(@"???????");
}
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)showTheAlertViewWithMassage:(NSString *)massage
{
UIAlertView *alertV = [[UIAlertView alloc] initWithTitle:@"温馨提示" message:massage delegate:self cancelButtonTitle:@"确定" otherButtonTitles: nil];
[alertV show];
}
- (void)openTheDoor
{
NSLog(@"拿到了可读可写的特征了");
// self.peripheral.delegate = self;
// characteristic.value = [string dataUsingEncoding:NSUTF8StringEncoding];
// characteristic.value = [NSData dataWithBytes:string.UTF8String length:string.length];
// [self.peripheral writeValue:data forCharacteristic:self.characteristic type:CBCharacteristicWriteWithResponse];
// [self.peripheral setNotifyValue:NO forCharacteristic:self.characteristic];
[self writeString:@"OLWANDA_IL12345678"];
}
- (void) writeString:(NSString *) string
{
NSData *data = [NSData dataWithBytes:string.UTF8String length:string.length];
// NSLog(@"%@",self.characteristic.UUID.UUIDString);
self.peripheral.delegate=self;
NSLog(@"%@",self.peripheral.delegate);
if ((self.characteristic.properties & CBCharacteristicPropertyWriteWithoutResponse) != 0)
{
[self.peripheral writeValue:data forCharacteristic:self.characteristic type:CBCharacteristicWriteWithoutResponse];
}
else if ((self.characteristic.properties & CBCharacteristicPropertyWrite) != 0)
{
[self.peripheral writeValue:data forCharacteristic:self.characteristic type:CBCharacteristicWriteWithResponse];
}
else
{
NSLog(@"No write property on TX characteristic, %ld.", self.characteristic.properties);
}
// <CBCharacteristic: 0x17408f500, UUID = 6E400002-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0xC, value = (null), notifying = NO>
}
iOS蓝牙--CoreBluetooth基本使用的更多相关文章
- iOS蓝牙开发(二)蓝牙相关基础知识
原文链接: http://liuyanwei.jumppo.com/2015/07/17/ios-BLE-1.html iOS蓝牙开发(一)蓝牙相关基础知识: 蓝牙常见名称和缩写 MFI ====== ...
- https://github.com/coolnameismy/BabyBluetooth github上的一个ios 蓝牙4.0的库并带文档和教程
The easiest way to use Bluetooth (BLE )in ios,even bady can use. 简单易用的蓝牙库,基于CoreBluetooth的封装,并兼容ios和 ...
- iOS蓝牙BLE4.0通信功能
概述 iOS蓝牙BLE4.0通信功能,最近刚学的苹果,为了实现蓝牙门锁的项目,找了一天学习了下蓝牙的原理,亲手测试了一次蓝牙的通信功能,结果成功了,那么就把我学习的东西分享一下. 详细 代码下载:ht ...
- 蓝牙(CoreBluetooth)-外部设备(服务端)
蓝牙(CoreBluetooth)-外部设备(服务端) 主要内容 1. 创建外部管理器对象 2. 设置本地外设的服务和特征 3. 添加服务和特征到到你的设置的数据库中 4. 向外公布你的的服务 5. ...
- 蓝牙(CoreBluetooth)-概述
蓝牙(CoreBluetooth)-概述 通过此框架可以让你的Mac和iOS应用程序与外部蓝牙设备通信 外部设备: 就是需要通过iOS App控制器的其他设备: 例如:心率检测仪.数字温控器 蓝牙通讯 ...
- ios 蓝牙相关
ios蓝牙开发项目实战 -(附小米手环实例) 前言 最近一直在开发关于蓝牙的功能,本来是不想写这一篇文章,因为网上关于ios蓝牙开发的文章实在太多了,成吨成吨的文章出现,但是很遗憾都只是一些皮 ...
- iOS蓝牙4.0开发
文/starfox寒流(简书作者)原文链接:http://www.jianshu.com/p/974d165f78b5著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. iOS 蓝牙4.0 ...
- iOS蓝牙BLE开发
蓝牙是一个标准的无线通讯协议,具有设备成本低.传输距离近和功耗低等特点,被广泛的应用在多种场合.蓝牙一般分为传统蓝牙和BLE两种模式:传统蓝牙可以传输音频等较大数据量,距离近.功耗相对大:而BLE则用 ...
- iOS 蓝牙开发资料记录
一.蓝牙基础认识: 1.iOS蓝牙开发: iOS蓝牙开发:蓝牙连接和数据读写 iOS蓝牙后台运行 iOS关于app连接已配对设备的问题(ancs协议的锅) iOS蓝牙空中 ...
随机推荐
- java零碎知识(每种数据类型默认值,多大,取值范围)
只要记下字节就好了 其它不必死记,取值范围:没有正负的,2的 字节数*8次方-1 , 凡是有正负的2的 (字节数*8)-1次方 -1 比如: 1.byte(有正负):先计算是2的几次方:字节数1*( ...
- 树莓派(4B)Linux + .Net Core嵌入式-HelloWorld(二)
一.新建.Net Core项目 新建.Net Core3.0的控制台应用,代码如下 namespace Demo { class Program { static void Main(string[] ...
- JVM系列一:JVM内存模型
今天起开始总结JVM.自己也看了好多JVM相关的知识,在此做个总结. 打算分为五个部分来讲:JVM内存模型.JVM类加载机制.JVM垃圾回收机制.JVM启动参数设置及优化.JVM其他相关. 今天首先来 ...
- [Luogu2967] 视频游戏的麻烦Video Game Troubles
农夫约翰的奶牛们游戏成瘾!本来约翰是想要按照调教兽的做法拿她们去电击戒瘾的,可是 后来他发现奶牛们玩游戏之后比原先产更多的奶.很明显,这是因为满足的牛会产更多的奶. 但是,奶牛们在哪个才是最好的游 ...
- OpenvSwitch系列之ovs-ofctl命令使用
Open vSwitch系列之一 Open vSwitch诞生 Open vSwitch系列之二 安装指定版本ovs Open vSwitch系列之三 ovs-vsctl 命令使用 OpenvSwit ...
- Cassandra官方介绍及安装
Cassandra官方介绍及安装 这个数据库有很高的伸缩性和可用性,你完全不需要向性能妥协.在硬件或者云设施上做修改 官网:Cassandra官网 一.简介 cassandra这个数据库有很高的伸缩性 ...
- 再谈 APISIX 高性能实践
2019 年 8 月 31 日,OpenResty 社区联合又拍云,举办 OpenResty × Open Talk 全国巡回沙龙·成都站,APISIX 主要作者王院生在活动上做了<APISIX ...
- 使用Wireshark成功解决JavaWeb项目的页面一直加载中的问题
现象 打开 服务器页面 10.2.155.100,然后发现页面JS显示 加载中..F12浏览器看起来像是发起css等静态资源时卡死.一时定位还以为时 前端的问题. 解决过程 上服务器抓包: tcpdu ...
- django-模板之if语句(九)
- 如何使用git上传代码
首先在github 上创建好远程仓库,并拷贝仓库地址,接下来按照以下步骤: 1.打开命令行进入要上传的文件目录,初始化 git init 2. 建立远程仓库,git remote add ori ...