低功耗藍牙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}];

這個的掃描速度更慢……

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章