iOS-蓝牙(CoreBlueTooth)
2017-07-07 本文已影响588人
指头飞血
iOS蓝牙须知
iOS提供了4个框架用于实现蓝牙连接
1.gameKit.framework(用法简单)
只能用于iOS设备之间的连接,多用于游戏(比如五子棋游戏),从iOS7开始过期(请参考http://www.jianshu.com/p/f58e57f1b424)
2.MultipeerConnectivity.framework
只能用于iOS设备之间的连接,从iOS7开始引入,主要用于文件共享(仅限于沙盒的文件)
3.ExternalAccessory.frameWork
可用于第三方蓝牙设备交互,但是蓝牙设备必须经过苹果MFi认证(国内较少)
4.CoreBluetooh.framework(时下热门)
可用于第三方蓝牙设备交互,必须要支持蓝牙4.0(硬件至少是4s,系统至少iOS6,蓝牙4.0以低功耗著称,一般也叫BLE(Bluetooth low Energy) 目前应用比较多的案例:运动手环,嵌入式设备,智能家居)
Core Bluetooth框架简介
Core Bluetooth基本常识
1.每个蓝牙4.0设备都是通过服务(Service)和特征(Characteristic)来展示自己的
2.一个设备必然包含一个或多个服务,每个服务下面又包含若干个特征
3.特征是与外界交互的最小单位(比如说:一个蓝牙4.0设备,用特征A来描述自己的出场信息,用特征B来收发数据)
4.服务和特征都是用UUID来唯一标识的,通过UUID就能区分不同的服务和特征
5.设备里面的各个服务(Service)和特征(Characteristic)的功能,均由蓝牙设备硬件厂商提供,比如那些是用来交互(读写),那些可获取模块信息(只读)等
Core Bluetooth的开发步骤
1.建立中心设备(手机)
2.扫描外围设备(Discover Peripheral)
3.连接外围设备(Connect Peripheral)
4.扫描外围设备的服务和特征(Discover Service and Characteristic)
5.利用特征与外围设备做数据交互(Explore And Interact)
6.断开连接(Disconnect)
如何让iOS模拟器也能测试蓝牙4.0程序
1.买一个CSR蓝牙4.0USB适配器,插在Mac上
2.在终端输入 sudo nvram bluetoothHostControllerSwitchBehavior="never"
3.重启Mac
上代码
//
// ViewController.m
// 蓝牙(CoreBlueTooth)
//
// Created by ws on 2017/6/14.
// Copyright © 2017年 王松. All rights reserved.
//
#import "ViewController.h"
#import <CoreBluetooth/CoreBluetooth.h>
@interface ViewController ()<CBCentralManagerDelegate,CBPeripheralDelegate>
///中央管理者
@property(nonatomic,strong)CBCentralManager*mgr;
///存储扫描到的外围设备
@property(nonatomic,strong)NSMutableArray*peripherals;
@end
@implementation ViewController
-(NSMutableArray *)peripherals{
if (!_peripherals) {
_peripherals = [NSMutableArray array];
}
return _peripherals;
}
#pragma mark 1.建立中央管理者
-(CBCentralManager *)mgr{
if (!_mgr) {
//1.建立中央管理者
self.mgr = [[CBCentralManager alloc]initWithDelegate:self queue:nil];
}
return _mgr;
}
#pragma mark CBCentralManager必须实现方法
/**
状态发生改变的时候会执行该方法(蓝牙4.0没有打开变成打开状态就会执行该方法)
*/
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
//判断状态
if (central.state) {
}
}
#pragma mark 扫描到外围设备执行的代理方法
/**
当发现外围设备的时候会调用该方法
@param peripheral 发现的外围设备
@param advertisementData 外围设备发出的信号
@param RSSI 信号强度
*/
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *, id> *)advertisementData RSSI:(NSNumber *)RSSI{
//先判断 如果我的数组里面已经包含了某个外围设备就不存储啦
if (![self.peripherals containsObject:peripheral]) {
[self.peripherals addObject:peripheral];
}
}
#pragma mark 用户连接外围设备
-(void)connect:(CBPeripheral *)peripheral{
//连接外围设备
[self.mgr connectPeripheral:peripheral options:nil];
}
#pragma mark 连接到某一个外围设备就会调用该代理方法
/**
连接到某一个外围设备所走的方法
@param peripheral 连接上的外围设备
*/
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
//1.扫描所有的服务
//参数:指定扫描该外围设备的那些服务(nil 表示扫描该外围设备的所有服务)
[peripheral discoverServices:nil];
//2.设置外围设备的代理
peripheral.delegate = self;
}
#pragma mark CBPeripheralDelegate外围设备的代理方法
/**
发现扫描到该外围设备的服务的时候执行该方法(扫描到服务之后直接添加到peripheral.services数组对象里面)
*/
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(nullable NSError *)error{
//对扫描到的该外围设备的服务进行遍历
for (CBService *service in peripheral.services) {
//拿到你想要的某个服务
if ([service.UUID.UUIDString isEqualToString:@"某个服务的UUID"]) {
NSLog(@"拿到你想要的某个服务");
//扫描服务里面的所有特征
//参数1:CBUUID:可以指定这个服务里想要扫描的特征(nil 表示扫描这个服务里面的所有的特征)
[peripheral discoverCharacteristics:nil forService:service];
}
}
}
/**
当扫描某一个服务的特征的时候会执行该方法(扫描到特征之后直接添加到service.characteristics数组对象里面)
@param service 在哪一个服务里的特征
*/
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
for (CBCharacteristic *characteristic in service.characteristics) {
if ([characteristic.UUID.UUIDString isEqualToString:@"某个特征的UUID"]) {
//拿到特征 和外围设备进行交互
//读
// [peripheral readValueForCharacteristic:characteristic];
//写
// peripheral writeValue:<#(nonnull NSData *)#> forCharacteristic:<#(nonnull CBCharacteristic *)#> type:<#(CBCharacteristicWriteType)#>
}
}
}
- (void)viewDidLoad {
[super viewDidLoad];
//1.建立中央管理者
//2.扫描所有的外围设备
//参数1:CBUUID 可以将你想要扫描的服务的外围设备传入(传nil表示扫描所有的外围设备)
//参数2:什么操作
[self.mgr scanForPeripheralsWithServices:nil options:nil];
}