天天看點

低功耗藍牙ibeacon的初級應用低功耗藍牙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}];
           

這個的掃描速度更慢……

繼續閱讀