低功耗蓝牙ibeacon的初级应用

低功耗蓝牙ibeacon的初级应用

1、直接CoreBluetooth API这是针对蓝牙的API,并不特指低功耗蓝牙,直接上代码:

    #import <CoreBluetooth/CoreBluetooth.h>
    //<CBCentralManagerDelegate,CBPeripheralDelegate>这两协议是需要遵守的,前一个是扫描相关的代理,后一个是连接后相关的代理
    //central是执行扫描的一个执行者
    @property(strong,nonatomic)CBCentralManager *central;
    -(void)viewdidLoade{
    //初始化并设置代理和运行线程
        self.central = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
        }
    #pragma -mark -CentralManagerDelegate
    //在central初始化后,会首先进入这个代理,CBCentralManagerStatePoweredOn状态证明蓝牙功能是正常的,然后scanForPeripheralsWithServices调用,开始搜索附近蓝牙设备,@{CBCentralManagerScanOptionAllowDuplicatesKey:@YES}这个option是让扫描可以重复扫同一个设备。
    - (void)centralManagerDidUpdateState:(CBCentralManager *)central{
    if(central.state == CBCentralManagerStatePoweredOn){
        [self.central scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey:@YES}];
    }
}
//没扫描到一个设备一次都会调用此代理,返回相关信息,RSSI:信号,advertisementData:广播信息 peripheral:蓝牙对象
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{
    //code 进行数据相关操作
}
//如果有连接蓝牙设备的需要,通过此方法连接
    [self.central connectPeripheral:peripheral options:options];
//连接成功进入的代理,在这里为peripheral设置代理,并调用discover方法查询服务
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
    [self.delegata connectState:YES];
    peripheral.delegate = self;
    [peripheral discoverServices:nil];
}
//连接失败进入的代理
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
    [self.delegata connectState:NO];
}
//在discover方法调用后,此代理方法运行,会取得iBeacon服务uuid标识,选取目标service,调用discoverCharacteristics,去获得该服务内的所有特征符。
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
//    for (CBService* service in peripheral.services){
//        NSLog(@"%@",   service.UUID.UUIDString);
//        if ([service.UUID.UUIDString isEqualToString:@"FFF0"]) {
//            [peripheral discoverCharacteristics:nil forService:service];
//        }
//    }
    NSLog(@"%@",peripheral.services);
    [peripheral discoverCharacteristics:nil forService:[peripheral.services firstObject]];
}
//discoverCharacteristics后此代理调用,可取得目标服务的所有状态符信息
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
    for (CBCharacteristic *charact in service.characteristics) {
        NSLog(@"%@",charact.UUID.UUIDString);
    }
}

以上则是该框架下蓝牙的使用,当然只是一部分,peripgeral的代理方法还有很多。接下来看第二种简单使用

2、CoreLocation框架也有蓝牙部分,当然这是在beacon出现之后才有的,由于beacon多被用于位置信息方面,所有将这部分API放入了CoreLocation中

//调用框架,遵循代理,两个属性
#import <CoreLocation/CoreLocation.h>
<CLLocationManagerDelegate>
@property(strong,nonatomic)CLBeaconRegion *region;
@property(strong,nonatomic)CLLocationManager *manager;
-(void)start{
//这个扫描方式并不是扫描所有的蓝牙设备,而是有针对性的,region则是扫描的一个标准,uuidstr,对于每个ibeacon 都有uuid,这个扫描方式则是扫描具有相同uuid的设备,
    self.manager = [[CLLocationManager alloc] init];
    self.manager.delegate = self;
    self.region = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:uuidstr] identifier:identifier];
     //app扫描权限的询问
     [self.manager requestAlwaysAuthorization];
     //这个权限访问被允许后,才可以进入下面的操作
}
#programe delegate
//允许权限后,才能进入此方法,开启Monitoring模式,进入或者退出目标iBeacon的范围,
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{
    if (status == kCLAuthorizationStatusAuthorizedAlways) {
        self.region.notifyOnEntry=YES;
        self.region.notifyOnExit=YES;
        self.region.notifyEntryStateOnDisplay=YES;
        //能够进入这里才进行扫描操作
        [self.manager startMonitoringForRegion:self.region];
    }
}
//开启Monitoring模式,进入这个代理,locationmanager发送请求信息
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region{
    NSLog(@"request");
    [self.manager requestStateForRegion:self.region];
}
//请求之后调用此代理,如果已经在目标iBeacon范围内,择开启ranging模式
-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
    NSLog(@"determ");
    if (state == CLRegionStateInside)
    {
        //Start Ranging
        [self.manager startRangingBeaconsInRegion:self.region];
}

//进入iBeacon区域执行的代理,在此开启ranging模式
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    NSLog(@"Entered region");
    [self.manager startRangingBeaconsInRegion:self.region];

}
//退出iBeacon区域执行的代理,停止ranging模式
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
    NSLog(@"Exited region");
    [self.manager stopRangingBeaconsInRegion:self.region];
}

//开启ranging模式后,不断刷新执行的代理,返回beacon的实时信息(信号,主副值,距离等)
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region{
//扫描到beacon信息后后进入这里,beacons是此次符合要求的所有beacon设备,region当然是我们的中心标准设备。beacon是个CLBeacon的实例对象,其属性proximityUUID是uuid,major是主值,minor副值,用于表示每一个beacon设备,accuracy距离信息,rss信号强度,总之,所需要的信息,这里面基本都有了。
}

总结,两种模式都可以获得蓝牙信息,前者无目标,针对所有设备,后者目标性唯一,有针对性,一般只用于beacon设备,再者,前者扫描速度很快,而后者比起前面则会慢上许多了,本人感觉,后面的扫描速度大约在1s一次。。

3、此外,iOS后台运行限制比较多,app退出后台时可以执行部分功能,但是如果超过10分钟保持后台状态,任何行为都会被终止。beacon设备是允许在后台进行扫描的,当然效率也会降低,并且只针对明确的beacon设备,不能后才检测未知设备。

      首先,蓝牙的后台功能是需要plist文件的相关设置的,![plist.png](https://img-blog.csdn.net/20160226182210005)
      这两个是后台运行的前提,然后,iBeacon或者其他基站的广播数据包种必须有这个键值对   kCBAdvDataServiceUUIDs = ~~~   centermanager后台扫描必须执行 serviceuuid才能扫描到基站,并且频率不可控,而且比前台要低很多,
//第一个参数这是扫描指定的iBeacon,为数组,可设置多个,此类基站广播数据包中都会有kCBAdvDataServiceUUIDs== FFF0这个键,
[self.central scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:@"FFF0"]] options:@{CBCentralManagerScanOptionAllowDuplicatesKey:@YES}];

这个的扫描速度更慢……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值