ibeacon 技術記錄

weixin_34148340發表於2018-03-29

ibeacon是蘋果公司在ios7釋出的一款硬體,可以感知ibeacon的位置。
ibeacon 只是一個硬體裝置,具體我們不過多的聊了,因為我是做軟體,更關心程式碼怎麼寫。
使用ibeacon的一些代理方法,必須要開啟定位許可權。

  1. 開啟定位許可權,在plist檔案中加入 plist -> source code 新增一下程式碼
    <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
    <string>允許</string>
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>允許</string>
    <key>NSLocationAlwaysUsageDescription</key>
    <string>允許</string>

appdelegate中程式碼清單如下:

 CLAuthorizationStatus state =   [CLLocationManager authorizationStatus];
    switch (state) {
        case kCLAuthorizationStatusNotDetermined:
        {
            // 使用者沒有做出選擇
            if ([self.locationManger respondsToSelector:@selector(requestAlwaysAuthorization)]) {
            [self.locationManger requestAlwaysAuthorization];
            }
        }
            break;
        case kCLAuthorizationStatusRestricted:
        {
            // 沒有獲得使用者授權
            
        }
            break;
        case kCLAuthorizationStatusDenied:
        {
            // 使用者明確禁止了
            
        }
            break;
        case kCLAuthorizationStatusAuthorizedAlways:
        {
            // 使用者選擇總是執行訪問位置
        }
            break;
        case kCLAuthorizationStatusAuthorizedWhenInUse:
        {
            // 使用者選擇執行期間訪問位置
        }
            break;
            
        default:
            break;
    }
    

位置許可權獲取了。我們開始建立一個region 程式碼清單如下

- (CLBeaconRegion *)beaconRegion
{
    if (!_beaconRegion) {
        NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"00000000-1111-2222-3333-444444444444"];
        _beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:@"region"];
// 使用者離開ibeacon區域,會走退出的代理方法
// 感覺 YES 和NO 都不會影響----
        _beaconRegion.notifyOnExit = YES;
        _beaconRegion.notifyOnEntry = YES;
//  設定成Yes,每次螢幕點亮,都會呼叫locationManager:didDetermineState:forRegion:
        _beaconRegion.notifyEntryStateOnDisplay = YES;
    }
    return _beaconRegion;
}

建立region 有一下幾個方法

initWithProximityUUID:identifier:
initWithProximityUUID:major:identifier:
initWithProximityUUID:major:minor:identifier:

uuidmajorminor 都是ibeacon的一些屬性。。硬體工程師都會告訴你的。identifier就是region的標誌,目的是區分不同的region

兩種監聽方式:
startMonitoringForRegion:能監聽使用者的離開和進入,前臺後臺都能
startMonitoringForRegion :能監聽使用者距離ibeacon的距離等一些資訊,不能在後臺監聽

代理方法

- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
    // 離開
    NSLog(@"離開");
    LocalPush *localNotification = [[LocalPush alloc] init];
    localNotification.title = @"測試";
    localNotification.body = @"離開了";
    localNotification.soundName = nil;
    localNotification.delayTimeInterval = 0.0;
    [localNotification pushLocalNotification];
}

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    // 進入
    NSLog(@"進入");
    LocalPush *localNotification = [[LocalPush alloc] init];
    localNotification.title = @"測試";
    localNotification.body = @"進入了";
    localNotification.soundName = nil;
    localNotification.delayTimeInterval = 0.0;
    [localNotification pushLocalNotification];
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"失敗");
}

- (void)locationManager:(CLLocationManager *)manager
monitoringDidFailForRegion:(nullable CLRegion *)region
              withError:(NSError *)error
{
    NSLog(@"monitoringDidFail");
}

// 在後臺和APP被kill .. 設定了notifyEntryStateOnDisplay = yes ,每次點亮螢幕都會被呼叫
- (void)locationManager:(CLLocationManager *)manager
      didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
    if(state == CLRegionStateInside) {
        NSLog(@"locationManager didDetermineState INSIDE for %@", region.identifier);
    }
    else if(state == CLRegionStateOutside) {
        NSLog(@"locationManager didDetermineState OUTSIDE for %@", region.identifier);
    }
    else {
        NSLog(@"locationManager didDetermineState OTHER for %@", region.identifier);
    }
}

// 沒一秒執行一次
- (void)locationManager:(CLLocationManager *)manager
        didRangeBeacons:(NSArray<CLBeacon *> *)beacons inRegion:(CLBeaconRegion *)region
{
        for (CLBeacon *beacon in beacons) {
            NSLog(@" rssi is :%ld",(long)beacon.rssi);
            NSLog(@" beacon proximity :%ld",(long)beacon.proximity);
            NSLog(@" accuracy : %f",beacon.accuracy);
            NSLog(@" proximityUUID : %@",beacon.proximityUUID.UUIDString);
            NSLog(@" major :%ld",(long)beacon.major.integerValue);
            NSLog(@" minor :%ld",(long)beacon.minor.integerValue);
        }
}

總結注意點:
1、必須要開啟藍芽服務 (理解錯誤了,不需要開啟藍芽)
2、必須要開啟定位服務,如果想後臺和被kill的狀態下,必須是完全允許定位,而不是使用期間允許定位
3、只能監聽20個region

DEMO

密碼: j5rp

相關文章